\documentclass[12pt]{article}
\usepackage{times}
\usepackage{graphicx}
\usepackage{sidecap}
\usepackage{wrapfig}
\usepackage{fancyhdr}
\usepackage{amsmath}
\pagestyle{fancy}
\renewcommand{\baselinestretch}{1.2}
\newenvironment{mylisting}
{\begin{list}{}{\setlength{\leftmargin}{1em}}\item\scriptsize\bfseries}
{\end{list}}
\newenvironment{mylisting2}
{\begin{list}{}{\setlength{\leftmargin}{1em}}\item\scriptsize\bfseries}
{\end{list}}
\newenvironment{mylisting3}
{\begin{list}{}{\setlength{\leftmargin}{1em}}\item\scriptsize\bfseries}
{\end{list}}
\newenvironment{mylisting4}
{\begin{list}{}{\setlength{\leftmargin}{1em}}\item\scriptsize\bfseries}
{\end{list}}
\newenvironment{mylisting5}
{\begin{list}{}{\setlength{\leftmargin}{1em}}\item\scriptsize\bfseries}
{\end{list}}
\newenvironment{mylisting6}
{\begin{list}{}{\setlength{\leftmargin}{1em}}\item\scriptsize\bfseries}
{\end{list}}
\begin{document}
	\textbf{{\Huge Quark Gluon plasma Objective-C Computer Graphics supporting/system code}}
{\center{May 2, 2013, 
	Johan Ceuppens, Theo D'Hondt - Vrije Universiteit Brussel}}
\\

{\center{With thanks to : Ellie D'Hondt, the SOFT lab and the Open Source Community}}

{\large{\textbf{\center Abstract}}}
\\

	This is code which was developed for Java and Ambienttalk/2 systems to provide for computer graphics research. It is a mere illustration.

\section{ iOS game code }
\begin{mylisting}
\begin{verbatim}


/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "ByteCodeMachine.h"
#import "Hex.h"
#import "arm-lisp-config.h"

@interface NesAssemblerMachine : ByteCodeMachine {

}

- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2;
- (int)pushAssignment:(Hex*)hex with:(Hex*)hex2;
- (int)pushOperatorPlus:(Hex*)addr;
- (int)pushOperatorPlusConstant:(NSString*)val;
- (int)pushOperatorPlusSymbol:(Hex*)hex;
- (int)pushOperatorMulConstant:(NSString*)val;
- (int)pushOperatorMulSymbol:(Hex*)hex;
- (int)pushOperatorPlusPlus:(Hex*)addr;
- (int)pushOperatorPlusAssign:(Hex*)addr andAddress:(Hex*)addr2;
- (int)pushOperatorMinus:(Hex*)addr;
- (int)pushOperatorMinusMinus:(Hex*)addr;
- (int)pushOperatorMinusAssign:(Hex*)addr andAddress:(Hex*)addr2;
- (int)pushOperatorOr:(Hex*)addr;
- (int)pushOperatorBitwiseOr:(Hex*)addr;
- (int)pushOperatorAnd:(Hex*)addr;
- (int)pushOperatorBitwiseAnd:(Hex*)addr;
- (int)pushIf:(Hex*)addr;
- (int)pushElse:(Hex*)addr;
- (int)pushPreviousLabel;

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import <UIKit/UIKit.h>

@interface AllAboutImagesAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
	UIButton *redButton;
	UIButton *greenButton;
	UIButton *blueButton;
	
	//UIWindow *window;
}

@property (nonatomic,retain) IBOutlet UIButton *redButton;
@property (nonatomic,retain) IBOutlet UIButton *greenButton;
@property (nonatomic,retain) IBOutlet UIButton *blueButton;

- (IBAction)doRedButton;
- (IBAction)doGreenButton;
- (IBAction)doBlueButton;

@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;



@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "Hex.h"
typedef int MACHINETYPE;

enum {
	HAVE_MACHINE_JAVA = 2,
	HAVE_MACHINE_ARMASM = 3,
	HAVE_MACHINE_6502ASM = 4,
	HAVE_MACHINE_ARMBYTE = 5,
	HAVE_MACHINE_6502BYTE = 6,
};

@interface ByteCodeMachine : NSObject {

	int _type;
	NSMutableArray* _bytecode;//strings
	int _freeaddycounter;//for storing variables
	int _freelabelcounter;
}

- (int)type;
- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2;
- (int)pushAssignment:(Hex*)hex with:(Hex*)hex2;
- (int)pushOperatorPlus:(Hex*)addr;
- (int)pushOperatorPlusConstant:(NSString*)val;
- (int)pushOperatorPlusSymbol:(Hex*)addr;
- (int)pushOperatorMinusConstant:(NSString*)val;
- (int)pushOperatorMinusSymbol:(Hex*)addr;
- (int)pushOperatorMulConstant:(NSString*)val;
- (int)pushOperatorMulSymbol:(Hex*)addr;
- (int)pushOperatorPlusPlus:(Hex*)addr;
- (int)pushOperatorPlusAssign:(Hex*)addr andAddress:(Hex*)addr2;
- (int)pushOperatorMinus:(Hex*)addr;
- (int)pushOperatorMinusMinus:(Hex*)addr;
- (int)pushOperatorMinusAssign:(Hex*)addr andAddress:(Hex*)addr2;
- (int)pushOperatorOr:(Hex*)addr;
- (int)pushOperatorBitwiseOr:(Hex*)addr;
- (int)pushOperatorAnd:(Hex*)addr;
- (int)pushOperatorBitwiseAnd:(Hex*)addr;
- (int)pushWhile:(Hex*)addr;
- (int)pushLoopDefaultRegister;
- (int)pushLoopGoto;
- (int)pushLoadSymbol:(Hex*)hex;
- (int)pushLoadConstant:(Hex*)hex;
- (int)pushIf:(Hex*)addr;
- (int)pushIfConstant:(int)addr;
- (int)pushIfDefaultRegister;
- (int)pushElse:(Hex*)addr;
- (int)pushPreviousLabel;
- (int)pushNewLabel;

- (int)generateFreeAddress;
- (NSString*)generateFreeLabel;

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#import <UIKit/UIKit.h>
#import "GameView.h"

@interface Enemy : NSObject {
	//NSMutableArray *mapImages;
	UIImage *enemyImages[1024];//FIXME C prog disease
	int x,y,w,h;
}

- (id) ctor;
- (UIImage*) render:(int)r;

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import <UIKit/UIKit.h>
//#import <EventKitUI/EventKitUI.h>
#import "GameSubView.h"

//#define SCREENWIDTH 16*8
//#define SCREENHEIGHT 16*8

@interface EnemySubView : GameSubView {
	//int x,y,w,h;
	//UIViewController* controller;
	NSMutableString* direction;
}

/*
@property (nonatomic,retain) IBOutlet UIButton *redButton;
@property (nonatomic,retain) IBOutlet UIButton *greenButton;
@property (nonatomic,retain) IBOutlet UIButton *blueButton;

- (IBAction)doRedButton;
- (IBAction)doGreenButton;
- (IBAction)doBlueButton;
*/
- (void)doRedButton;
- (void)foo;
- (id) initx:(int)xx y:(int)yy w:(int)ww h:(int)hh;
//-(void) keyDown: (NSEvent *)event;

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.


#import <UIKit/UIKit.h>
//#import <EventKitUI/EventKitUI.h>
#import "GameView.h"
#import "GameSubView.h"
#import "EnemySubView.h"
#import "Map.h"
#import "Player.h"
#import "Enemy.h"

#define IPADXOFFSET 200
#define IPADYOFFSET 200

@interface FirstViewController : UIViewController {
    //UIImageView* mImageView;
	GameView* mImageView;
	
	UIImage *mapImages[1024];
	
	GameSubView *subviews[16][16];
	GameSubView *playersubviews[1];
	EnemySubView *enemysubviews[1024];
	int nenemysubviews;
	
	int x,y;
	float fx;
	
	
	int xoffset,yoffset;
	
	Map *map;
	Player *player;
	Enemy *enemy;

	UIButton *redButton;
	UIButton *greenButton;
	UIButton *blueButton;
	UIButton *alphaButton;
	
	UIButton *interactButton;
	
	//UIWindow *window;
}

- (void) setx:(int)xx y:(int)yy;
- (void)move;

@property (nonatomic,retain) IBOutlet UIWindow *window;

@property (nonatomic,retain) IBOutlet UIButton *redButton;
@property (nonatomic,retain) IBOutlet UIButton *greenButton;
@property (nonatomic,retain) IBOutlet UIButton *blueButton;
@property (nonatomic,retain) IBOutlet UIButton *alphaButton;
@property (nonatomic,retain) IBOutlet UIButton *interactButton;

- (IBAction)doRedButton;
- (IBAction)doGreenButton;
- (IBAction)doBlueButton;
- (IBAction)doAlphaButton;
- (IBAction)doInteractButton;

@property (nonatomic, retain) IBOutlet /*UIImageView**/GameView* imageView;//NOTE

- (IBAction)contentModeChanged:(UISegmentedControl*)segmentedControl;

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import <UIKit/UIKit.h>
//#import <EventKitUI/EventKitUI.h>

//#define SCREENWIDTH 16*8
//#define SCREENHEIGHT 16*8

@interface GameSubView : UIImageView {
	int x,y,w,h;
	UIViewController* controller;
	
}

/*
@property (nonatomic,retain) IBOutlet UIButton *redButton;
@property (nonatomic,retain) IBOutlet UIButton *greenButton;
@property (nonatomic,retain) IBOutlet UIButton *blueButton;

- (IBAction)doRedButton;
- (IBAction)doGreenButton;
- (IBAction)doBlueButton;
*/
- (void)doRedButton;
- (void)foo;
- (id) initx:(int)xx y:(int)yy w:(int)ww h:(int)hh controller:(UIViewController*)p;
//-(void) keyDown: (NSEvent *)event;

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import <UIKit/UIKit.h>
//#import <EventKitUI/EventKitUI.h>
#import "Map.h"
@class GameSubView;

#define SCREENWIDTH 16*8
#define SCREENHEIGHT 16*8

@interface GameView : UIImageView {
	int x,y,w,h;
	UIViewController* controller;
	UIButton *redButton;
	UIButton *greenButton;
	UIButton *blueButton;
	
	//UIWindow *window;
	GameSubView *subviews[16][16];
}


@property (nonatomic,retain) IBOutlet UIButton *redButton;
@property (nonatomic,retain) IBOutlet UIButton *greenButton;
@property (nonatomic,retain) IBOutlet UIButton *blueButton;

- (IBAction)doRedButton;
- (IBAction)doGreenButton;
- (IBAction)doBlueButton;

- (id) init;
- (void)drawRect:(CGRect)rect;
//-(void) keyDown: (NSEvent *)event;

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#import <UIKit/UIKit.h>
#import "GameView.h"

static int map1[16][16] = { 3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
};

@interface Map : NSObject {
	//NSMutableArray *mapImages;
	UIImage *mapImages[1024];//FIXME C prog disease
	int w,h;
}

- (id) ctor;
- (UIImage*) renderx:(int)xx y:(int)yy;

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#import <UIKit/UIKit.h>
#import "GameView.h"

@interface Player : NSObject {
	//NSMutableArray *mapImages;
	UIImage *playerImages[1024];//FIXME C prog disease
	int w,h;
	
	NSString *direction;
}

- (id) ctor;
- (UIImage*) render:(int)r;

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.


#import <UIKit/UIKit.h>


@interface SecondViewController : UIViewController {
    
}

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#import <Foundation/Foundation.h>

/*
@interface ThreeButtonsAppDelegate : NSObject {
	UIButton *redButton;
	UIButton *greenButton;
	UIButton *blueButton;
	
	UIWindow *window;
}

@property (nonatomic,retain) IBOutlet UIWindow *window;

@property (nonatomic,retain) IBOutlet UIButton *redButton;
@property (nonatomic,retain) IBOutlet UIButton *greenButton;
@property (nonatomic,retain) IBOutlet UIButton *blueButton;

- (IBAction)doRedButton;
- (IBAction)doGreenButton;
- (IBAction)doBlueButton;

@end
*//*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "6502AssemblerMachine.h"

@implementation NesAssemblerMachine

- (NesAssemblerMachine*)ctor
{
	_type = HAVE_MACHINE_6502ASM;
	_freeaddycounter = 0;

	NSLOG(@"*** arm-lisp running for 6502 target");
	NSLOG(@"*** Non-Heap, 6502 assembly target - Hex number system loaded");

	return self;
}

- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2
{
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"sta ", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ $%@", @"lda ", [hex2 hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"6502 : pushed definition with lda $%@ and sta #%@",[hex hexnumberstring],[hex2 hexnumberstring]);
	return 0;
}

- (int)pushAssignment:(Hex*)hex with:(Hex*)hex2
{
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"sta ", [hex2 hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	return 0;
}

- (int)pushOperatorPlus:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"adc ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorPlusConstant:(Hex*)hex
{
	//lda reg
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"adc ", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG(@"6502 : pushed Plus Constant");
	return 0;
}

- (int)pushOperatorPlusSymbol:(Hex*)hex
{
	//lda reg
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"adc ", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG(@"6502 : pushed Plus Symbol");
	return 0;
}

- (int)pushOperatorMulConstant:(Hex*)hex
{
	//lda reg
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"FIXME mul ", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG(@"6502 : pushed Mul Constant");
	return 0;
}

- (int)pushOperatorMulSymbol:(Hex*)hex
{
	//lda reg
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"FIXME mul ", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG(@"6502 : pushed Mul Symbol");
	return 0;
}

- (int)pushOperatorMinus:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"sbc ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorPlusPlus:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"inc ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorMinusMinus:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"dec ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorPlusAssign:(Hex*)addr andAddress:(Hex*)addr2
{
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"lda ", [addr hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"adc ", [addr2 hexnumberstring]];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorMinusAssign:(Hex*)addr andAddress:(Hex*)addr2
{
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"lda ", [addr hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"sbc ", [addr2 hexnumberstring]];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorOr:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"ora ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushOperatorBitwiseOr:(Hex*)addr
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"ora ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushOperatorBitwiseExclusiveOr:(Hex*)addr
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"eor ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushOperatorBitwiseAnd:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"and ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushOperatorBitwiseOrAssign:(Hex*)addr andAddress:(Hex*)addr2
{

	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"lda ", [addr hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"ora ", [addr2 hexnumberstring]];//FIXME ORA ?
	[_bytecode addObject: s2];
	[_bytecode addObject: s];

}

- (int)pushOperatorBitwiseExclusiveOrAssign:(int)addr andAddress:(int)addr2
{

	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"lda ", [addr hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"eor ", [addr2 hexnumberstring]];//FIXME ORA ?
	[_bytecode addObject: s2];
	[_bytecode addObject: s];

}

- (int)pushOperatorAnd:(int)addr
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"and ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushOperatorBitwiseAndAssign:(int)addr andAddress:(int)addr2
{

	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"lda ", [addr hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"and ", [addr2 hexnumberstring]];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushIf:(Hex*)hex
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateLabel]];
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"cmp ", [hex hexnumberstring]];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushLoadSymbol:(Hex*)hex
{
	NSString *s = [NSString stringWithFormat:@"%@ $%@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	NSLOG2(@"6502 assembler : pushed load symbol with lda $%@",[hex hexnumberstring]);
	return 0;
}

- (int)pushLoadConstant:(Hex*)hex
{
	NSString *s = [NSString stringWithFormat:@"%@ #%@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	NSLOG2(@"6502 assembler : pushed load symbol with lda #%@",[hex hexnumberstring]);
	return 0;
}
- (int)pushIfConstant:(int)i
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateLabel]];
	NSString *s2 = [NSString stringWithFormat:@"%@ %d", @"cmp ", i];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushLoopDefaultRegister
{
	//TODO
	return 0;
}
- (int)pushLoopGoto
{
	//TODO
	return 0;
}
- (int)pushIfDefaultRegister
{
	//TODO
/*	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateLabel]];
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"cmp ",];
	NSString *s3 = [NSString stringWithFormat:@"%@ %@", @"lda ",];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;
*/
	return 0;
}

- (int)pushElse:(Hex*)hex
{

	NSString *s2 = [NSString stringWithFormat:@"bcc label%@:", _freelabelcounter];//if before jump over else clause, FIXME bcc ?
	NSString *s = [NSString stringWithFormat:@"label%@:", [self generateLabel]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	return 0;

}

- (int)pushWhile:(Hex*)hex
{

	NSString *s2 = [NSString stringWithFormat:@"bcc label%@", _freelabelcounter];//branch after while block code, FIXME bcc ?
	NSString *s = [NSString stringWithFormat:@"label%@:", [self generateLabel]];//loop; label
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	return 0;

}

- (int)pushPreviousLabel
{

	NSString *s = [NSString stringWithFormat:@"label%@:",_freelabelcounter];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushNewLabel
{

	NSString *s = [NSString stringWithFormat:@"label%@:",[self generateFreeLabel]];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushBranch:(Hex*)hex
{

	NSString *s = [NSString stringWithFormat:@"bcc %@",_freelabelcounter];
	[_bytecode addObject: s];
	return 0;
}


- (NSString*)getLastLabel 
{
	//TODO 
	return 0;
}
@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.


#import "AllAboutImagesAppDelegate.h"

@implementation AllAboutImagesAppDelegate


@synthesize window=_window;

@synthesize tabBarController=_tabBarController;

//@synthesize window;
//@synthesize redButton,greenButton,blueButton;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    // Add the tab bar controller's current view as a subview of the window
    self.window.rootViewController = self.tabBarController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
     */
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
     */
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    /*
     Called when the application is about to terminate.
     Save data if appropriate.
     See also applicationDidEnterBackground:.
     */
}

- (void)dealloc
{
    [_window release];
    [_tabBarController release];
    [super dealloc];
}

- (IBAction)doRedButton{ /*window.backgroundColor = [UIColor redColor];*/}
- (IBAction)doGreenButton{/*window.backgroundColor = [UIColor greenColor];*/}
- (IBAction)doBlueButton{/*window.backgroundColor = [UIColor blueColor];*/}

//- (IBAction)doRedButton{ self.imageView.backgroundColor = [UIColor redColor]; x+=10;[self move];UIImage *image = [UIImage imageNamed:@"t16tiles"]; self.imageView.image = image;/*window.backgroundColor = [UIColor redColor];*/}
//- (IBAction)doGreenButton{self.imageView.backgroundColor = [UIColor greenColor]; x-=10;[self move];/*window.backgroundColor = [UIColor greenColor];*/}
//- (IBAction)doBlueButton{ self.imageView.backgroun

/*
// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
}
*/

/*
// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed
{
}
*/

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ArmAssemblerMachine.h"

@implementation ArmAssemblerMachine

- (ArmAssemblerMachine*)ctor
{
	_type = HAVE_MACHINE_ARMASM;
	_freeaddycounter = 0;
	return self;
}

- (int)pushLoadSymbol:(Hex*)hex
{
	NSString *s = [NSString stringWithFormat:@"%@, #0x%@", @"ldr r0", [hex hexnumberstring]];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed load symbol with ldr r0, #0x%@",[hex hexnumberstring]);
	return 0;
}

- (int)pushLoadConstant:(Hex*)hex
{
	NSString *s = [NSString stringWithFormat:@"%@, =%@", @"ldr r0", [hex hexnumberstring]];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed load constant with ldr r0, =%@",[hex hexnumberstring]);
	return 0;
}

- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2
{
	NSString *s2 = [NSString stringWithFormat:@"%@, 0x%@", @"str r1", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@, =%@", @"ldr r1", [hex2 hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed definition with ldr r1, =%@ ; str r1,#0x%@ ; ",[hex2 hexnumberstring],[hex hexnumberstring]);
	return 0;
}

- (int)pushOperatorPlus:(Hex*)hex
{
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"add ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	NSLOG3(@"arm assembler : pushed plus r1,=%@ and str r0,=%@",[hex hexnumberstring],[hex hexnumberstring]);
	return 0;
}

- (int)pushOperatorPlusConstant:(NSString*)val
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"add "];
	NSString *s = [NSString stringWithFormat:@"%@, =%@", @"ldr r1", val];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed plus constant ldr r1,=%@ and add r0,r0,r1", val);
	return 0;
}

- (int)pushOperatorPlusSymbol:(Hex*)hex
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"add "];
	NSString *s = [NSString stringWithFormat:@"%@, #0x%@", @"ldr r1", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed plus symbol ldr r1,#0x%@ and add r0,r0,r1", [hex hexnumberstring]);
	return 0;
}

- (int)pushOperatorMinusConstant:(NSString*)val
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"sub "];
	NSString *s = [NSString stringWithFormat:@"%@, =%@", @"ldr r1", val];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed minus constant ldr r1,=%@ and sub r0,r0,r1", val);
	return 0;
}

- (int)pushOperatorMinusSymbol:(Hex*)hex
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"sub "];
	NSString *s = [NSString stringWithFormat:@"%@, #0x%@", @"ldr r1", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed minus symbol ldr r1,#0x%@ and sub r0,r0,r1", [hex hexnumberstring]);
	return 0;
}

- (int)pushOperatorMulConstant:(NSString*)val
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"mul "];
	NSString *s = [NSString stringWithFormat:@"%@, =%@", @"ldr r1", val];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed multiply constant ldr r1,=%@ and mul r0,r0,r1", val);
	return 0;
}

- (int)pushOperatorMulSymbol:(Hex*)hex
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"mul "];
	NSString *s = [NSString stringWithFormat:@"%@, #0x%@", @"ldr r1", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed multiply symbol ldr r1,#0x%@ and mul r0,r0,r1", [hex hexnumberstring]);
	return 0;
}

- (int)pushIf:(Hex*)hex
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateFreeLabel]];
	//NOTE major results are in r0 register (throughout this ArmAssemblerMachine.m file)
	NSString *s2 = [NSString stringWithFormat:@"%@", @"cmp r0,r1"];
	NSString *s3 = [NSString stringWithFormat:@"%@ #0x%@", @"ldr r1,", [hex hexnumberstring]];
	[_bytecode addObject: s3];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed if ldr r1,#0x%@ ; cmp r0,r1 ; bne labelX", [hex hexnumberstring]);
	return 0;
}

- (int)pushIfConstant:(int)i
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateFreeLabel]];
	//NOTE major results are in r0 register (throughout this ArmAssemblerMachine.m file)
	NSString *s2 = [NSString stringWithFormat:@"%@", @"cmp r0,r1"];
	NSString *s3 = [NSString stringWithFormat:@"%@ =%d", @"ldr r1,", i];
	[_bytecode addObject: s3];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	NSLOG3(@"arm assembler : pushed if constant ldr r1,=%d ; cmp r0,r1 ; bne label%d", i, _freelabelcounter);
	return 0;
}

- (int)pushIfDefaultRegister
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateFreeLabel]];
	//NOTE major results are in r0 register (throughout this ArmAssemblerMachine.m file)
	NSString *s2 = [NSString stringWithFormat:@"%@", @"cmp r0,r1"];
	NSString *s3 = [NSString stringWithFormat:@"%@", @"ldr r1,r0"];
	[_bytecode addObject: s3];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed if ldr r1,r0 ; cmp r0,r1 ; bne label%d",_freelabelcounter);
	return 0;
}

- (int)pushLoopDefaultRegister
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateFreeLabel]];
	//NOTE major results are in r0 register (throughout this ArmAssemblerMachine.m file)
	NSString *s2 = [NSString stringWithFormat:@"%@", @"cmp r0,r1"];
	NSString *s3 = [NSString stringWithFormat:@"%@", @"ldr r1,r0"];
	[_bytecode addObject: s3];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed loop condition ldr r1,r0 ; cmp r0,r1 ; bne label%d",_freelabelcounter);
	return 0;

}
- (int)pushLoopGoto:(NSString*)l
{

	NSString *s = [NSString stringWithFormat:@"goto %@", l];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed goto %@",l);
	return 0;

}

- (int)pushPreviousLabel
{

	NSString *s = [NSString stringWithFormat:@"label%d:",_freelabelcounter];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed previous label%d:",_freelabelcounter);
	return 0;
}

- (int)pushNewLabel
{

	NSString *s = [NSString stringWithFormat:@"label%@:",[self generateFreeLabel]];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed new label%d:",_freelabelcounter);
	return 0;
}

- (NSString*)getLastLabel 
{
	NSString *s = [NSString stringWithFormat:@"label%d:",_freelabelcounter];
	return s;
} 

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "ArmLispCompiler.h"
#import "Hex.h"
#import "ParseTreeOp.h"
#import "6502AssemblerMachine.h"
#import "ArmAssemblerMachine.h"
#import "Word.h"

@implementation ArmLispCompiler

- (ArmLispCompiler*)ctor:(MACHINETYPE)i
{
	_symboltable = [[SymbolTable new] ctor];
	_typetable = [[TypeTable new] ctor];
	NSLOG(@"constructing...");
	_operatortable = [[OperatorTable new] ctor];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"+" andAddress:[[Hex alloc] ctorString:@"+"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"++" andAddress:[[Hex alloc] ctorString:@"++"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"1+" andAddress:[[Hex alloc] ctorString:@"1+"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"-" andAddress:[[Hex alloc] ctorString:@"-"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"1-" andAddress:[[Hex alloc] ctorString:@"1-"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"--" andAddress:[[Hex alloc] ctorString:@"--"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"*" andAddress:[[Hex alloc] ctorString:@"*"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"**" andAddress:[[Hex alloc] ctorString:@"**"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"/" andAddress:[[Hex alloc] ctorString:@"/"]]];
	//TODO add other operators
	//add arm bytecode, java bytecode, ...
	switch(i){
	case HAVE_MACHINE_6502ASM:{
		_machine = [[NesAssemblerMachine alloc] ctor];
		break; 
	}
	case HAVE_MACHINE_ARMASM:{ 
		_machine = [[ArmAssemblerMachine alloc] ctor];
		break; 
	}
	default:{
		_machine = [[ArmAssemblerMachine alloc] ctor];
		break; 
	}
	}
	NSLOG(@"done.");
	return self;
}

- (int)grepLines:(NSString*)buffer
{

	int i = -1;
	int lines = 0;
	while (++i && i < [buffer length]) {
		char c = [buffer characterAtIndex:i];
		if (c == '\n')
			lines++;	
	}
	return lines;
}

- (TupleInt*)grepWord:(FNString *)fileName withIndex:(int)idx
{
	NSString *s = @"";
	FileBuffer *buffer = [fileName buffer];

	while (++idx && idx < [buffer length]) {
		char c = [buffer characterAtIndex:idx];
		if (c == ' ' || c == '\t')
			return [[TupleInt new] addFirst:idx andSecond:s];
	
		s += c;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

- (TupleInt*)skipWhiteSpace:(NSString *)line withIndex:(int)idx
{
	NSString *s = @"";
	while (idx < [line length]) {
		char c = [line characterAtIndex:idx];
		if (c == ' ' || c == '\t')
			;
		else
			break;
		idx++;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

- (TupleInt*)searchForWeenie:(NSString *)line withIndex:(int)idx
{
	NSString *s = @"";
	while (++idx && idx < [line length]) {
		char c = [line characterAtIndex:idx];
		if (c != ';')
			;
		s += c;
	}

	return [[TupleInt new] addFirst:idx andSecond:s];
}

- (TupleInt*)grepWordOfLine:(NSString*)line withIndex:(int)idx
{
	//skip prevailing whitespace
	TupleInt *ti = [self skipWhiteSpace:line withIndex:idx];
	idx = [ti first];
	//idx--;

	NSString *s = @"";
	while (idx < [line length]) {
		char c = [line characterAtIndex:idx++];
		if (c == ' ' || c == '\t')
			return [[TupleInt new] addFirst:idx andSecond:s];
	
		s += c;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

/*
 * 1. grep word until parens encounterd '(' or ')'
 * 2. grep word starting with parens '('
 */
- (TupleInt*)grepWordOfLineParens:(NSString*)line withIndex:(int)idx
{
//	NSLOG2(@"parens s=%@",line);
//	NSLOG2(@"parens1 idx=%d",idx);
	//skip prevailing whitespace
	//int idx2 = idx; 
	TupleInt *ti = [self skipWhiteSpace:line withIndex:idx];
	//idx = [ti first];
	//if (idx2 != idx)
	//	idx--;
//	NSLOG2(@"parens2 idx=%d",idx);

	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	while (idx < [line length]) {
		char c = [line characterAtIndex:idx];
//		NSLOG2(@"parens c=%c",c);
		if (c == ' ' || c == '\t') 
			return [[TupleInt new] addFirst:idx andSecond:s];

		if ((c == '(' || c == ')') && idx > 0) {
			//s += c;
			[s appendFormat:@"%c",c];
			idx++;
			return [[TupleInt new] addFirst:idx andSecond:s];
		}
		[s appendFormat:@"%c",c];
		//s += c;
		idx++;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

/*
 * This gets a single word or form from formstring (non reversed form!) 
 */
- (NSString*)grepFormOrWord:(NSString*)formstring withIndex:(int)idx
{
	//skip prevailing whitespace
	int nopen = 0;
	int nclosed = 0;
	TupleInt *ti = [self skipWhiteSpace:formstring withIndex:idx];
	idx = [ti first];
	//Form *form = [[Form alloc] initWithString:@""];
	NSLOG3(@"grepping for wordorform in = %@ idx=%d",formstring,idx);
	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	while (idx < [formstring length]) {
		char c = [formstring characterAtIndex:idx];
		if ((c = [formstring characterAtIndex:idx]) == '(') {
			nopen++;//NOTE formstring is reversed
			[s appendFormat:@"%c",c];
		} else if ((c = [formstring characterAtIndex:idx]) == ')') {
			nclosed++;//NOTE formstring is reversed
			if (nopen == nclosed && nopen != 0 && nclosed != 0) {
				[s appendFormat:@"%c",c];
				//[form setString:s];
				//Form get formatted inherently with fomatLisp
				//in the above ctor
				NSLOG2(@"*** grepped form = %@",s);
				//return form;
				return s;
			}
		} else if (nopen == 0 && (c == ' ' || c == '\t')) { 
			//[form setString:s];
			//Form get formatted inherently with fomatLisp
			//in the above ctor
			NSLOG2(@"*** grepped word = %@",s);
			return s;
		} else {
			[s appendFormat:@"%c",c];
		}
		//s += c;
		idx++;
	}

	NSLOG2(@"*** no word or form = %@ - raise error",s);
	//Form get formatted inherently with fomatLisp
	return s;
}

- (TupleInt*)grepWordOfLineParensAndChomp:(NSString*)line withIndex:(int)idx
{
//	NSLOG2(@"parens s=%@",line);
//	NSLOG2(@"parens1 idx=%d",idx);
	//skip prevailing whitespace
	//int idx2 = idx; 
	TupleInt *ti = [self skipWhiteSpace:line withIndex:idx];
	idx = [ti first];
	//if (idx2 != idx)
	//	idx--;
//	NSLOG2(@"parens2 idx=%d",idx);

	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	while (idx < [line length]) {
		char c = [line characterAtIndex:idx];
//		NSLOG2(@"parens c=%c",c);
		if (c == ' ' || c == '\t') 
			return [[TupleInt new] addFirst:idx andSecond:s];

		if ((c == '(' || c == ')') && idx > 0)
			return [[TupleInt new] addFirst:idx andSecond:s];
		[s appendFormat:@"%c",c];
		//s += c;
		idx++;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

- (TupleInt*)getRestOfForm:(NSString*)formstring withIndex:(int)idx
{
	//FIXME ?
	//TupleInt *ti = [self skipWhiteSpace:formstring withIndex:idx];
	//idx = [ti first];
	//skip prevailing whitespace
	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	while (idx < [formstring length]) {
		char c = [formstring characterAtIndex:idx++];
		[s appendFormat:@"%c",c];
	}

	return [[TupleInt new] addFirst:idx andSecond:s];
}

- (TupleInt*)getRestOfFormAndChomp:(NSString*)formstring withIndex:(int)idx
{
	//skip prevailing whitespace
	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	while (idx < [formstring length]-1) {
		char c = [formstring characterAtIndex:idx++];
		[s appendFormat:@"%c",c];
	}

	return [[TupleInt new] addFirst:idx andSecond:s];
}

- (TupleInt*)grepWord:(NSString*)needleword OfWord:(NSString*)haystackword withIndex:(int)idx
{
	//FIXME use indexOf
	NSString *s = @"";
	while (idx++ < [haystackword length]) {
		int idx2;
		for (idx2 = 0; idx2 < [needleword length]; idx2++) {
			if ([haystackword characterAtIndex:idx+idx2] != [needleword characterAtIndex:idx2])
				break;
		}
		if ([needleword length] == idx2) {
			while (idx++ < [haystackword length])
				s += [haystackword characterAtIndex:idx];
				
			return [[TupleInt new] addFirst:idx andSecond:s];	
		}
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

/*
 * returns the line rest after needleword
 */
- (TupleInt*)grepWordOfLine:(NSString*)line withWord:(NSString*)needleword withIndex:(int)idx
{
	//skip prevailing whitespace
	//int idx2 = idx; 
	TupleInt *ti = [self skipWhiteSpace:line withIndex:idx];
	idx = [ti first];
	//if (idx2 != idx)
	//	idx--;
	//FIXME use indexOf
	NSString *s = @"";
	while (idx++ < [line length]) {
		int idx2 = 0;
		for (idx2 = 0; idx2 < [needleword length]; idx2++) {
			if ([line characterAtIndex:idx+idx2] != [needleword characterAtIndex:idx2])
				break;
		}
		if ([needleword length] == idx2) {
			while (idx++ < [line length])//concat rets of line
				s += [line characterAtIndex:idx];
				
			return [[TupleInt new] addFirst:idx andSecond:s];	
		}
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

- (NSString*)grepLine:(FNString *)fileName withIndex:(int)idx
{
	NSString *s = @"";
	FileBuffer *buffer = [fileName buffer];

	while (++idx && idx < [buffer length]) {
		char c = [buffer characterAtIndex:idx];
		if (c == '\n')
			return s;
	
		s += c;
	}

	return @"";
}
	
- (int)compilablesource:(NSString*)filename {
	
	//FileBuffer *buffer = [fileName buffer];

	//int i = -1;
	//while (++i < [buffer length]) {
	//i = [self parseFile:fileName withIndex:i];
	FNString *fn = [[FNString alloc] ctor:filename];
	[fn readInFile];
	[self parseFile:fn withIndex:0];
	//}

	return 0;
}

- (int) parseFile:(FNString*)fn withIndex:(int)idx 
{
	NSString *str = [fn bufferstring];
	
//	NSString *st;
//	st = [NSString stringWithFormat:@"str=%@", str];
//	NSLOG(st);	
	Form *f	= [[Form alloc] initWithString:str];
	if (f == nil)
		return 0;//NOTE nil form or @"" formstring
	[self parseForms:f withIndex:idx];

	return 0;
}

/*
 * This is a Lisp file's form parser, if forms
 * are encountered which can be put into the symbol or
 * type table they are transferred there with a symbol's
 * value equal to the form's code
 *
 * If the forms are to be executed they need another loop
 * through the form parser so they get executed
 * 
 * example 1 :
 * 
 * (defvar x 1 "This is the documentation of 1")
 * 
 * The form "1 "This is the documemntation of 1"" is
 * put into the symbol's name x with address [[Hex alloc] ctorString:"x"]
 * in the _symboltable of this parser. It gets immediately translated to 
 * e.g. 6502 assembly with "sta 1"
 * 
 * example 2 :
 * 
 * (defun y () (return-from "123"))
 * 
 * The only thing that happens with this is that it gets set
 * in the _symboltable with [[Hex alloc] ctorString:"y"] as an address
 */
- (int) parseForms:(Form*)form withIndex:(int)idx 
{
	NSLOG(@"parsing Forms...");
	NSString *formstring = [form string];

	int linest = [self grepLines:formstring];

	int lines = 0;
	NSString *s = [[NSString alloc] initWithString:@""];
	while (idx < [formstring length]) {
		char c = [formstring characterAtIndex:idx];	

		if (c == '\n')
			lines++;
		idx++;
	}
	Form *subform;	
	int i = 0;
	//init the top-level environment of this file's forms
	NSMutableArray* array;// = [NSMutableArray new];
	array = [self splitForms:formstring];//split
	if (array == nil /*|| [array length] == 0*/) { 
		NSLOG(@"Form array is nil@");
		return -1;
	}
	NSEnumerator *iter = [array objectEnumerator];
	//set below idx += [form length];//NOTE
	while (subform = [iter nextObject]/* && subform != nil*/) {
		[subform reverse];//NOTE
		NSLOG3(@"%@ %@", @"Processing Form",[subform string]);
		int r = [self parseFormForDefinition:subform];

		/* a definition gets added to the symbol or typetable
		 * defvar, deftype respectively
		 * deftype only generates a type in the typetable
		 * There is no machine instruction for type definitions
		 * on an ARM, 6502 etc.
                 */
		if (r == 0xdef) {//definition
			NSString *st;
			st = [NSString stringWithFormat:@"%@", @"have definition." ];	
			//[form addStatus:HAVE_DEFINITION String:st];
			NSLOG(st);
			continue;
		} else {
			r = [self parseFormForOperator:subform];
			if (r == 0xabc) {//operator
				NSString *st;
				st = [NSString stringWithFormat:@"%@", @"have operator." ];	
				//[form addStatus:HAVE_OPERATOR String:st];	
				NSLOG(st);
				continue;
			} else {
				r = [self parseFormForIf:subform];
				if (r == 0x333) {//if
					NSString *st;
					st = [NSString stringWithFormat:@"%@", @"have if." ];	
					//[form addStatus:HAVE_IF String:st];	
					NSLOG(st);
					continue;
				} else r = [self parseFormForLoop:subform];
				if (r == 0x444) {//if
					NSString *st;
					st = [NSString stringWithFormat:@"%@", @"have loop." ];	
					//[form addStatus:HAVE_LOOP String:st];	
					NSLOG(st);
					continue;
				}
				
			}
		}
	}
/* TODO
	if ([[fileName getLastStatus] first] == HAVE_IF) {//next subform
		subform = [self grepLine:fileName withIndex:idx];
		subform = [ self reverse: subform ];//NOTE
		int r2 = [self parseLineForElseClause:subform];
		if (r2 < 0) //no else clause found
			return idx;
		else if (r2 == 5) 
			[fileName addStatus:HAVE_ELSE String:&st];
		else if (r2 == 2) {	
			[fileName addStatus:HAVE_CLOSINGBRACE String:&st];
			[fileName addStatus:HAVE_ELSE String:&st];
		} else if (r2 == 3) {	
			[fileName addStatus:HAVE_CLOSINGBRACE String:&st];
			[fileName addStatus:HAVE_ELSE String:&st];
			[fileName addStatus:HAVE_OPENINGBRACE String:&st];
		} else {
		}
		idx += [subform length];
		[_machine pushElse:[Hex ctor: [_lastsymbol address]]];
	}
	}*/
	
	NSLOG(@"Reached end of form.");
	return 0;
}

- (int) parseAtom:(Form*)form withIndex:(int)idx 
{
	NSLOG(@"parsing Atom...");
	NSString *formstring = [form string];
		//[subform reverse];//NOTE
	NSLOG3(@"%@ %@", @"Processing Atom",[form string]);

	switch((TYPE)[self getTypeOfString:formstring]) {
	case (const TYPE)itype:
		[_machine pushLoadConstant:[[Hex alloc] ctorInt: atoi([formstring UTF8String])]];
		break;	
	case (const TYPE)symtype:
	default:{
		Hex *varhex = [[Hex new] ctorString:[form string]];
		Symbol *s2 = [_symboltable searchForHex: varhex ];
		int address;
		if (s2 == nil) 
			address = -1;
		else
			address = [[s2 address] number];
	
		//check if variable's address exists
		if (address < 0) {
			//TODO raise error
			NSLOG(@"Syntax Error (parseAtom) : unknown value of variable");
			return -1;
		} else {
			//compare address in if clause for true or false
			[_machine pushLoadSymbol:varhex];	
		}
		break;
	}
	}

/*	int r = [self parseFormForDefinition:form];
	if (r == 0xdef) {//definition
		NSString *st;
		st = [NSString stringWithFormat:@"%@", @"have definition." ];	
		//[form addStatus:HAVE_DEFINITION String:st];
		NSLOG(st);
	} else {
		r = [self parseFormForOperator:form];
		if (r == 0xabc) {//operator
			NSString *st;
			st = [NSString stringWithFormat:@"%@", @"have operator." ];	
			//[form addStatus:HAVE_OPERATOR String:st];	
			NSLOG(st);
		} else {
			r = [self parseFormForIf:form];
			if (r == 0x333) {//if
				NSString *st;
				st = [NSString stringWithFormat:@"%@", @"have if." ];	
				//[form addStatus:HAVE_IF String:st];	
				NSLOG(st);
			}
		}
	}
*/	return 0;
}

- (int) parseFormForDefinition:(Form*)form//NOTE form has been reversed reversed (human readable code string)
{

	NSLOG(@"parse for definition...");
	NSString *formstring = [form string];
	TupleInt *ti = [self grepWordOfLineParens:formstring withIndex:0 ];


	//NSLOG(@"word=%@", (NSString*)[ti second]);
	NSString *sti;
	sti = [NSString stringWithFormat:@"%@", (NSString*)[ti second]];
	//NSLOG(@"stiword=%@", sti);
	//check for type definition
	if ([sti compare: @"(deftype"] == 0) {
		NSLOG(@"deftype definition");
		//construct hex out of NSString*word which is the type after deftype
		TupleInt* ti2 = NULL;
		Tuple *t = [[Tuple new] addFirst:[ti second] andSecond:NULL ];
		NSString *word = [ t first ];
		int idx = [ti first];
		Hex *hex = [[Hex new] ctor:word];

		//check if word is already defined
		int hexint = [_typetable searchForHex: hex];//TODO return Type* instead of hexint

		//NOTE FIXME big endian system, bit per bit parsing of ids
		//check if hex needs updating

		//NOTE do not forget Lisp changes its native types, so type in typetable needs to be overwritten
		while (hexint != 0x0000) {
			int h = h | hexint;
			//switch on Native Lisp type (integer, char, ...) 
			switch (hexint & 0x1000) {
			case (const TYPE)ctype:{//ctype, character type
				continue;
				break;
			}
			case (const TYPE)itype:{//itype const, integer
				
				if ([[self parsehexandset: h] first] == 0x0000) 
					continue; 
				else {// hex is e.g. 0x02 for int (itype) 
					ti2 = [self grepWordOfLineParens:formstring withIndex:[ti first]];
					idx = [ti2 first];
					[self parseDefinitionOfdeftype:ti2];
					//goto lableassignment;
				}
				break;
			}
			//FIXME vtype 4 and other types
			default:{
				break;
			}
			}
			hexint <<= 2;
	
		}
		return 0xdef;
	} else if ([sti compare: @"(defvar"] == 0) {
		NSLOG(@"defvar definition");
		//NSLOG2(@"1--->%@",[ti second]);

		TupleInt* ti2;
		TupleInt* ti3;
		TupleInt* ti4;
		
		//example : (defvar x 1)
		//get name of free variable (x)
		ti2 = [self grepWordOfLineParens:formstring withIndex:[ti first]];
		//NSLOG3(@"2--->%@ idx=%d",[ti2 second],[ti2 first]);
		ti4 = [self getRestOfForm:formstring withIndex:[ti2 first]];
		//get value of free variable (1)
		//NSLOG2(@"rest of form--->%@",[ti4 second]);
		TupleInt *ti5 = [self hasSubForms:[ti4 second]];
		if ([ti5 first] < 0) {
			ti3 = [self grepWordOfLineParensAndChomp:formstring withIndex:[ti2 first]];
			//NSLOG2(@"5--->%@",[ti3 second]);
			[self parseDefinitionOfdefvar:ti2 and:ti3];//evals to formstring or simple statement
		} else {
			ti3 = [self getRestOfFormAndChomp:formstring withIndex:[ti2 first]];
			//NSLOG2(@"5--->%@",[ti3 second]);
			[self parseDefinitionOfdefvarWithForm:ti2 and:ti3];//evals to formstring or simple statement
		} 
		return 0xdef;
	} else if ([sti compare: @"(setq"] == 0 || [sti compare: @"(setf"] == 0) {
		NSLOG(@"setq or setf definition");

		TupleInt* ti2;
		TupleInt* ti3;
		TupleInt* ti4;
		TupleInt* ti5;
		
		ti3 = [self skipWhiteSpace:formstring withIndex:[ti first]];
		//example : (setq x 1)
		//get name of free variable (x)
		ti2 = [self grepWordOfLineParens:formstring withIndex:[ti3 first]];
		NSLOG2(@"definition sym=%@ ",[ti2 second]);
		ti4 = [self getRestOfFormAndChomp:formstring withIndex:[ti2 first]];
		//get value of free variable (1)
		//evals to formstring or simple statement
		//ti5 = [self hasSubForms:[ti4 second]];
		NSString *s5 = [self grepFormOrWord:formstring withIndex:[ti2 first]];
		NSLOG2(@"definition sym5=%@ ",s5);
		if ([s5 characterAtIndex:0] != '(') {
			//ti3 = [self grepWordOfLineParensAndChomp:formstring withIndex:[ti2 first]];
			NSLOG3(@"def sym=%@ val=%@",[ti2 second],[ti4 second]);
			[self parseDefinitionOfsetfq:ti2 and:ti4];
		} else {
			ti3 = [self getRestOfFormAndChomp:formstring withIndex:[ti2 first]];
			[self parseDefinitionOfsetfqWithForm:ti2 and:ti4];//evals to formstring or simple statement
		} 

		return 0xdef;
	} else {
		NSLOG(@"No definition");
		return 0x000;//NOTE
	}
	return 0x000;//NOTE
}

- (int) parseFormForOperator:(Form*)form//NOTE line has been reversed reversed
{
	NSLOG(@"parsing for operator...");
	NSString *formstring = [form string];
	int idx = 0;

	while (idx++ < [formstring length]) {

		TupleInt *ti = [self grepWordOfLineParens:[form string] withIndex:1];//NOTE 1
		idx = [ti first];
		Operator *op = [_operatortable getOperator:[ti second]];
		if (op == nil) {//Operator does not exist, no definition or declaration found
			NSLOG(@"no matching operator not found");
			return 0x000;
		} 

		//NOTE rest of form is even parensed by splitForms: above
		ti = [self getRestOfForm:formstring withIndex:idx];
		//idx = [ti first];
		NSLOG2(@"rest of form=%@", [ti second]);	

	
		return [self parseOperator:[op string] form:[[Form alloc] initWithString:[ti second]]];
	}
	return 0x000;
}

- (int) parseLineForAssignmentWithOperator:(NSString*)line//NOTE line has been reversed reversed
{
	TupleInt *ti = [self grepWordOfLine:line withIndex:0];
	int idx = [ti first];
	if ([ti second] == @"") {
		return 0x000;
	}
	Symbol *s = [_symboltable getString:[ti second]];
	if (s == NULL) {//Symbol does not exist, no definition or declaration found
		return 0x000;
	} else {
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:s];
	}

	ti = [self grepWordOfLine:line withIndex: idx];
	idx = [ti first];

	if ([ti second] != @"=" || [ti second] == @"==") {
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove

		return 0x0000;
	} 
	
	while (++idx && idx < [line length] && [line characterAtIndex:idx] != ';') {

		ti = [line grepWordOfLine:line withIndex:idx];
		idx = [ti first];
		Symbol *s = [_symboltable getString:[ti second]];//FIXME numbers instead of symbols
		if (s == NULL) {//Symbol does not exist, no definition or declaration found
			return 0x000;
		} else if ( [self checkTypeOf:s and:[[_parsetreestatus second] type]] < 0 ) {
			//invalid return/previous type	
			return 0x0000;	

		} else {
			_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:s];
		}
	
		ti = [line grepWordOfLine:line withIndex:idx];
		idx = [ti first];

		[self parseOperator:[ti second] withAddress:[Hex ctor:[[ti second] address]] andAddress:[Hex ctor: [s address]]];
	}
	_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove
	int weenieidx = [[self searchForWeenie:line withIndex:idx] first];
	if (idx < [line length] && idx <= weenieidx)
		return 0xabc;
 
	if (weenieidx >= [line length])
			return 0x000;//FIXME addError

	return 0x000;
}

- (int) parseLineForAssignment:(NSString*)line//NOTE line has been reversed reversed
{
		
	_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove

}

- (int) parseFormForIf:(Form*)form//NOTE line has been reversed reversed
{
	TupleInt* ti = [self grepWordOfLineParens:[form string] withIndex:0];
	Word *w = [[Word alloc] ctor: [ti second]];//NOTE form

	if ([w isParensIf] < 0 || [w isIfClause] < 0) {	
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove
		return 0x000;
	}

	if ([self parseFormForIfClause:[[Form alloc] initWithString:[form string]]] == 0x333) {
		//[_machine pushPreviousLabel];
		
		return 0x333;
	}
}

- (int) parseFormForLoop:(Form*)form//NOTE line has been reversed reversed
{
	TupleInt* ti = [self grepWordOfLineParens:[form string] withIndex:0];
	Word *w = [[Word alloc] ctor: [ti second]];//NOTE form

	if ([w isParensLoop] < 0 /*|| [w isIfClause] < 0*/) {	
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove
		return 0x000;
	}

	if ([self parseFormForLoopClause:[[Form alloc] initWithString:[form string]]] == 0x444) {
		//[_machine pushPreviousLabel];
		
		return 0x444;
	}
}

- (int) parseLineForWhile:(NSString*)line//NOTE line has been reversed reversed
{
	Word *w = [Word ctor: line];//NOTE line

	if ([w isWhile] < 0 || [w isWhileClause] < 0) {	
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove
		return 0x000;
	}

	[_machine pushNewLabel];
	if ([self parseLineForWhileClause:line] == 0x444) {
		[_machine pushBranch:[Hex ctor: [_lastsymbol address]]];
		
		return 0x444;
	}
}

- (int) parseFormForLoopClause:(Form*)form
{
	//generate loop label and push it
	[_machine pushNewLabel];
	NSString *looplabel = [_machine getLastLabel];
	
	int idx = [self skipWordAndWhiteSpace:form withIndex:0];
	NSLOG2(@"P=%d",idx);
	Form *f = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];

	if ([[f string] compare: @"while"] == 0) {

		NSLOG(@"got Loop while");

		int idx = [self skipWordAndWhiteSpace:form withIndex:0];
		//loop condition is atom
		if ([[form string] characterAtIndex:idx] != '(') {
			idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			Form *f2 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			[self parseAtom:f2 withIndex:0];	

			[_machine pushLoopDefaultRegister];

			idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			NSLOG2(@"W=%d",idx);
			TupleInt* ti = [self grepWordOfLine:[form string] withIndex:idx];
			NSLOG2(@"W=%d",[ti first]);
			//if ([[ti second] compare: @"do"] == 0) {
				//TODO != '(', isForm
				NSLOG(@"do of loop");
				idx = [self skipWordAndWhiteSpace:form withIndex:idx];
				Form *f3 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				//[f3 reverse];
				if ([[f3 string] characterAtIndex:0] != '(') {	
					[self parseAtom:f3 withIndex:0];	
					[_machine pushLoopGoto:looplabel];
					[_machine pushPreviousLabel];

				} else {

					[self parseForms:f3 withIndex:0];	
					[_machine pushLoopGoto:looplabel];
					[_machine pushPreviousLabel];
				}
			return 0x444;
			//}
		} else {
		//loop condition is form
			idx = [self skipFormAndWhiteSpace:form withIndex:idx];
			Form *f2 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			[self parseForms:f2 withIndex:0];	

			[_machine pushLoopDefaultRegister];

			idx = [self skipFormAndWhiteSpace:form withIndex:idx];
			Form *f3 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			[self parseForms:f3 withIndex:0];	
			[_machine pushLoopDefaultRegister];
			return 0x444;
		}

	}
	return 0x000;
}

- (int) parseFormForIfClause:(Form*)form
{
	NSLOG(@"Parsing If Clause");
	int idx = [self skipWordAndWhiteSpace:form withIndex:0];
	NSLOG2(@"P=%d",idx);
	Form *f = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
	NSLOG2(@"ISFORM=%@",[f string]);
	//if ([f isForm] < 0) {
	if ([[f string] characterAtIndex:0] != '(') {
		//found symbol or value
		//if ([_lastsymbol isKindOfClass:[Symbol class]]) {
		switch ((TYPE)[self getTypeOfString: [f string]]) {
		case (const TYPE)itype:
			[_machine pushIfConstant:atoi([[f string] UTF8String])];//TODO use value to type value conversion within Symbol
			//TODO parsing of true and false clauses	
			break;
		case (const TYPE)symtype:
		default:{
			Hex *varhex = [[Hex new] ctorString:[f string]];
			Symbol *s2 = [_symboltable searchForHex: varhex ];
			int address;
			if (s2 == nil) 
				address = -1;
			else
				address = [[s2 address] number];
	
			//check if variable's address exists
			if (address < 0) {
				//TODO raise error
				NSLOG(@"Syntax Error : unknown value of variable");
				return -1;
			} else {
				//compare address in if clause for true or false
				[_machine pushIf:[[Hex alloc] ctorInt: address]];
			}
		}	
		}//switch
		idx = [self skipWordAndWhiteSpace:form withIndex:idx];
		NSLOG2(@"P=%d",idx);
		Form *ff = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
		
		//if ([f isForm] < 0) {
		//true clause is not a form
		if ([[ff string] characterAtIndex:0] != '(') {
			[self parseAtom:ff withIndex:0];

			idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			NSLOG2(@"P=%d",idx);
			Form *fff = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			
			if ([[fff string] compare:@""] == 0 || [[fff string] compare:@")"] == 0 || [[fff string] compare:@"\n"] == 0) {
				NSLOG(@"* no else clause");
				return 0x333;	
			}
			//if ([f isForm] < 0) {
			//else clause is not a form

			if ([[fff string] characterAtIndex:0] != '(') {
				[_machine pushPreviousLabel];
				[self parseAtom:fff withIndex:0];
				return 0x333;
			} else {//else clause is form
				[_machine pushPreviousLabel];
				[self parseForms:fff withIndex:0];
				return 0x333;
			}
		} else {//true clause is form
			NSLOG2(@"ff str=%@", [ff string]);
			[ff reverse];//FIXMENOTETODO
			[self parseForms:ff withIndex:0];
			[_machine pushPreviousLabel];

			idx = [self skipFormAndWhiteSpace:ff withIndex:idx];
			Form *form4 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
		
			NSLOG2(@"form4 string=%@",[form4 string]);
	
			/*if ([[form4 string] compare:@""] == 0 || [[form4 string] compare:@")"] == 0 || [[form4 string] compare:@"\n"] == 0) {
				NSLOG(@"* no else clause");
				return 0x333;	
			}*/
			//else clause is not a form
			//if ([f isForm] < 0) {
			if ([[form4 string] characterAtIndex:0] != '(') {
				idx = [self skipWordAndWhiteSpace:ff withIndex:idx];
				//Form *form11 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				//[form11 reverse];
				//[self parseForms:form11 withIndex:0];
				[self parseAtom:form4 withIndex:0];
				return 0x333;
			} else {//else clause is form
				idx = [self skipFormAndWhiteSpace:form withIndex:idx];
				Form *form10 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				[form10 reverse];
				[self parseForms:form10 withIndex:0];
				return 0x333;
			}
			return 0x333;
		}
	} else {//if clause is form
		NSLOG2(@"if clause is form=%@", [f string]);
		[f reverse];
		[self parseForms:f withIndex:0];
		[_machine pushIfDefaultRegister];
		NSLOG2(@"f =%@",[f string]);
		idx += [[f string] length];
		idx = [self skipWordAndWhiteSpace:form withIndex:idx];
		NSLOG2(@"P=%d",idx);
		Form *ff = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
		
		//true clause is atom	
		//if ([f isForm] < 0) {
		if ([[ff string] characterAtIndex:0] != '(') {
			[self parseAtom:ff withIndex:0];
			[_machine pushPreviousLabel];
			idx = [self skipFormAndWhiteSpace:ff withIndex:idx];
			//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			Form *form5 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			
			if ([[form5 string] compare:@""] == 0 || [[form5 string] compare:@")"] == 0 || [[form5 string] compare:@"\n"] == 0) {
				NSLOG(@"* no else clause");
				return 0x333;	
			}
			//else clause is not a form
			//if ([f isForm] < 0) {
			if ([[form5 string] characterAtIndex:0] != '(') {
				NSLOG2(@"form5 atom string=%@",[form5 string]);
				[self parseAtom:form5 withIndex:0];
				idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
				Form *form9 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				[form9 reverse];
				[self parseForms:form9 withIndex:0];
				return 0x333;
			} else {//else clause is form
				NSLOG2(@"form5 form string=%@",[form5 string]);
				idx = [self skipFormAndWhiteSpace:form withIndex:idx];
			//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
				Form *form6 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				[self parseForms:form6 withIndex:0];
				return 0x333;
			}
		//true clause is form
		} else {
			[ff reverse];
			[self parseForms:ff withIndex:0];
			[_machine pushPreviousLabel];
			//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			idx = [self skipFormAndWhiteSpace:form withIndex:idx];
			Form *form5 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			
			if ([[form5 string] compare:@""] == 0 || [[form5 string] compare:@")"] == 0 || [[form5 string] compare:@"\n"] == 0) {
				NSLOG(@"* no else clause");
				return 0x333;	
			}
			//else clause is not a form
			NSLOG3(@"--------->%@ idx=%d",[form5 string],idx);
			Form *form6 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			//if ([f isForm] < 0) {
			if ([[form6 string] characterAtIndex:0] != '(') {
				Form *form7 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				[self parseAtom:form7 withIndex:0];
				idx = [self skipWordAndWhiteSpace:form withIndex:idx];
				Form *form8 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				if ([[form8 string] characterAtIndex:0] != '(') {
					[self parseAtom:form7 withIndex:0];
				}
				return 0x333;
			} else {//else clause is form
				[form6 reverse];
				[self parseForms:form6 withIndex:0];
				return 0x333;
			}
		}
		return 0x333;
	}
	
	//}
	//}
//	[_machine pushIf:[[Hex alloc] ctorInt: [[_lastsymbol address] number]]];
//		return 0x333;
/*	 else {
		if ([_machine type] != HAVE_MACHINE_6502ASM)
			[_machine pushIfDefaultRegister];//TODO
		return 0x000;
	}
*/
/*	r = [self parseLineForAssignmentWithOperator:[form string]];
	if (r == 0xabc) {//assignment with op 
		[_machine pushIf:[Hex ctor: [_lastsymbol address]]];
		return 0x333;
	}
*/
	return 0x000;
}
/*
- (int) parseLineForElseClause:(NSString*)line
{
	TupleInt *ti = [self skipWhiteSpace:line withIndex:0];
	int idx = [ti first];

	while (idx < [line length]){
	switch ([line characterAtIndex:idx++]){
	case '}':{
		continue;	
		break;
	}
	case ' ':{
		continue;	
		break;
	}
	default:{
		Word *w4 = [Word ctor:line];
		if ([w4 isElseClause]) {
			return [w4 isElseClause];

	} else {//if clause is form
		NSLOG2(@"is form = %@",[f string]);
		[f reverse];
		[self parseForms:f withIndex:0];
		[_machine pushIfDefaultRegister];
		return 0x333;
	}
	//}
	//}
//	[_machine pushIf:[[Hex alloc] ctorInt: [[_lastsymbol address] number]]];
//		return 0x333;
*//*	 else {
		if ([_machine type] != HAVE_MACHINE_6502ASM)
			[_machine pushIfDefaultRegister];//TODO
		return 0x000;
	}
*/
/*	r = [self parseLineForAssignmentWithOperator:[form string]];
	if (r == 0xabc) {//assignment with op 
		[_machine pushIf:[Hex ctor: [_lastsymbol address]]];
		return 0x333;
	}
*/
/*	return 0x000;
}*/

- (int) parseLineForElseClause:(NSString*)line
{
	TupleInt *ti = [self skipWhiteSpace:line withIndex:0];
	int idx = [ti first];

	while (idx < [line length]){
	switch ([line characterAtIndex:idx++]){
	case '}':{
		continue;	
		break;
	}
	case ' ':{
		continue;	
		break;
	}
	default:{
		Word *w4 = [Word ctor:line];
		if ([w4 isElseClause]) {
			return [w4 isElseClause];
		}

		Word *w = [Word ctor:[[self grepWordOfLine:line withIndex:idx] second]];
		Word *w2 = [Word ctor:[[self grepWordOfLine:line withIndex:idx] second]];
		Word *w3 = [Word ctor:[[self grepWordOfLine:line withIndex:idx] second]];
		if ([w isElse]) {
			//goto lablepif;
			Word *w = [Word ctor:[self grepWordOfLine:line withIndex:idx]];
			return idx;
		} else if ([w isClosingBrace]) {
			if ([w2 isElse]) {
				if ([w3 isOpeningBrace])
					return 3;
				else
					return 2;
			}
		} else if ([ w2 isElse]) {
			return 5;
		}
		return 4;	
		break;
	}
	}
	}
	return -1;
	
//lablepif:

	////if ([w isClosingBrace] >= 0)
			
	return idx;
}
 
- (int)parseOperator:(NSString*)op form:(Form*)form
{

	int idx = 0;
	//NOTE skip '('
	//idx++;

	switch ([op characterAtIndex: 0]) {//character as e.g. '+', (in op string!)
	case '1':
	case '+':{
		//++,1+
		if ([op length] > 1) {
			//skip op
			idx ++;
			if ( [op characterAtIndex: 1] == '+') {//NOTE e.g. i++
			//[_machine pushOperatorPlusPlus:addr];
				//[self setLastSymbol:s];
				return 0xabc;
			}
		//+
		} else if ([op characterAtIndex:0] != '1') {
			//skip operator syntax '+'
			//idx++;
			//skip whitespace 
			//idx++;
			NSLOG2(@"with idx : %@",[form string]);
			TupleInt *ti = [self skipWhiteSpace:[form string] withIndex:idx];
			idx = [ti first];
			NSLOG2(@"with idx : %@",[ti second]);
			//TupleInt *ti5 = [self hasSubForms:[form string]];
			//if ([ti5 first] < 0) {
			NSString *s5 = [self grepFormOrWord:[form string] withIndex:idx];
			if ([s5 characterAtIndex:0] != '(') {
			//if ([[self hasSubForms:[form string]] first] < 0) {
				while (idx < [[form string] length]-1) {//-1 skip last parens
					TupleInt *ti = [self grepWordOfLineParensAndChomp:[form string] withIndex:idx];
					NSLOG2(@"with idx : %@",[ti second]);
					idx = [ti first];

					if ([self parsePlus:ti] != 0)
						return -1;
					idx++;
				}
				return 0xabc;
			} else {//if ([[self hasSubForms:[form string]] first] == 1) {
			TupleInt *ti5 = [self hasSubForms:[form string]];
			if ([ti5 first] < 0) {

				while (idx < [[form string] length]-1) {
					TupleInt *ti = [self grepWordOfLineParensAndChomp:[form string] withIndex:idx];
					idx = [ti first];

					if ([self parsePlus:ti] != 0)
						return -1;
					idx++;
				}	
				return 0xabc;

			}
			}	
		}
		break;
	}
	}

	switch ([op characterAtIndex: 0]) {//character as e.g. '+'
	case '1':
	case '-':{
		//--,1-
		if ([op length] > 1) {
			idx ++;
			if ( [op characterAtIndex: 1] == '-') {//NOTE e.g. i++
			//[_machine pushOperatorPlusPlus:addr];
			}
		//+
		} else if ([op characterAtIndex:0] != '1') {
			TupleInt *ti = [self skipWhiteSpace:[form string] withIndex:idx];
			idx = [ti first];
			TupleInt *ti5 = [self hasSubForms:[form string]];
			if ([ti5 first] < 0) {
				while (idx < [[form string] length]-1) {
					TupleInt *ti = [self grepWordOfLineParensAndChomp:[form string] withIndex:idx];
					idx = [ti first];

					if ([self parseMin:ti] != 0)
						return -1;
					idx++;
				}
				return 0xabc;
			}	
		}
		break;
	}
	case '*':{
		//**
		if ([op length] > 1) {
			idx ++;
			if ( [op characterAtIndex: 1] == '*') {//NOTE e.g. i++
			//[_machine pushOperatorMulMul:addr];
			}
		//*
		} else {
			TupleInt *ti = [self skipWhiteSpace:[form string] withIndex:idx];
			idx = [ti first];
			TupleInt *ti5 = [self hasSubForms:[form string]];
			if ([ti5 first] < 0) {
			//if ([[self hasSubForms:[form string]] first] < 0) {
				while (idx < [[form string] length]-1) {
					TupleInt *ti = [self grepWordOfLineParensAndChomp:[form string] withIndex:idx];
					idx = [ti first];

					if ([self parseMul:ti] != 0)
						return -1;
					idx++;
				}
				return 0xabc;
			}	
		}
		break;
	}
/*	case '|':{
		if ([op length] > 1 && [op characterAtIndex: 1] == '|')//NOTE || 
			;//[_machine pushOperatorOr:addr];//e.g. || 
		else
			;//[_machine pushOperatorBitwiseOr:addr];
		break;
	}
	case '&':{
		if ([op length] > 1 && [op characterAtIndex: 1] == '&')//NOTE || 
			;//[_machine pushOperatorAnd:addr];//e.g. || 
		else
			;//[_machine pushOperatorBitwiseAnd:addr];
		break;
	}
	case '^':{
		//[_machine pushOperatorBitwiseExclusiveOr:addr];
	}
*/	default:{
		break;
	}
	}

	return 0x000;
}
/*
- (int)parseOperator:(NSString*)op withAddress:(int)addr andAddress:(int)addr2
{
		switch ([op characterAtIndex: 0]) {//character as e.g. '+'
		case '+':{
			if ([op length] > 1 && [op characterAtIndex: 1] == '+')//NOTE e.g. i++
				[_machine pushOperatorPlusPlus:addr];
			else if ([op length] > 1 && [op characterAtIndex: 1] == '=')//NOTE e.g. i++
				[_machine pushOperatorPlusAssign:addr andAddress:addr2];//e.g. addr += addr2
			else
				[_machine pushOperatorPlus:addr];
			break;
		}
		case '-':{
			if ([op length] > 1 && [op characterAtIndex: 1] == '-')//NOTE e.g. i--
				[_machine pushOperatorMinusMinus:addr];
			else if ([op length] > 1 && [op characterAtIndex: 1] == '=')//NOTE e.g. i++
				[_machine pushOperatorMinusAssign:addr andAddress:addr2];//e.g. addr += addr2
			else
				[_machine pushOperatorMinus:addr];
			break;
		}
		case '|':{
			if ([op length] > 1 && [op characterAtIndex: 1] == '|')//NOTE e.g. i++
				[_machine pushOperatorOr:addr];
			else if ([op length] > 1 && [op characterAtIndex: 1] == '=')//NOTE e.g. i++
				[_machine pushOperatorBitwiseOrAssign:addr andAddress:addr2];//e.g. addr |= addr2
			else
				[_machine pushOperatorBitwiseOr:addr];
			break;
		}
		case '&':{
			if ([op length] > 1 && [op characterAtIndex: 1] == '&')//NOTE e.g. i++
				[_machine pushOperatorAnd:addr];
			else if ([op length] > 1 && [op characterAtIndex: 1] == '=')//NOTE e.g. i++
				[_machine pushOperatorBitwiseAndAssign:addr andAddress:addr2];//e.g. addr |= addr2
			else
				[_machine pushOperatorBitwiseAnd:addr];
			break;
		}
		case '^':{
			if ([op length] > 1 && [op characterAtIndex: 1] == '=')//NOTE e.g. i++
				[_machine pushOperatorBitwiseExclusiveOrAssign:addr andAddress:addr2];//e.g. addr |= addr2
			else
				[_machine pushOperatorBitwiseExclusiveOr:addr];
			break;
		}
		default:{
			break;
		}
		}
	return 0;
}
*/
- (TYPE)checkTypeOf:(Symbol*)sym and:(TYPE)t
{

	if ([sym type] == t)
		return t;

	if (([sym type] == ctype && t == itype) 
		|| 
		(t == ctype && [sym type] == itype)) 
		return itype;

	if ([_typetable hasType: [sym type]]) {//t is not used
		return [sym type];
	} 

	return -1;
}

- (TYPE)getTypeOfString:(NSString*)s
{
	NSLOG2(@"TYPE2=%@",s);
	if ([s compare: @"0"] != 0 && atoi([s UTF8String]) > 0) {
		NSLOG2(@"atoi=%d",atoi([s UTF8String]));
		return itype;
	}
	else if ([s compare: @"0"] != 0 && atof([s UTF8String]) > 0)
		return ftype;
	//character type also things like #\Linefeed
	else if ([s length] == 3 && [s characterAtIndex:0] == '#'
				 && [s characterAtIndex:1] == '\\'
				 && isascii([s characterAtIndex:2])) {
		return ctype;
	} else if ([s length] > 0 && [s characterAtIndex:0] == '"'
				&& [s characterAtIndex:[s length]-1] == '"')
		return stype;
	 else if ([s length] > 0)//TODO return -1 below
		return symtype;
	
/*
	if ([_typetable hasType: [s type]]) {//t is not used
		return [s type];
	} 
*/
	return -1;
}

- (TupleInt*) parsehexandset:(int)h 
{
	//big endian system
	switch (h) {
	case 0x00:{
		return 0;
	}
	case (const TYPE)ctype:{//ctype
		_parsetreestatus = [[TupleInt new] addFirst:ctype andSecond:@"char"]; 	
		break;
	}
	case (const TYPE)itype:{//itype
		_parsetreestatus = [[TupleInt new] addFirst:itype andSecond:@"integer"]; 	
		break;
	}
	case (const TYPE)vtype:{//vtype
		_parsetreestatus = [[TupleInt new] addFirst:vtype andSecond:@"void"]; 	
		break;
	}
	default:{
	}
	}	
	return _parsetreestatus;
}

- (int) parseDefinitionOfdeftype:(TupleInt*)status
{
	/*
	 * There is no machine instruction for type definitions
	 * on an ARM, 6502 etc.
	 * If a Lisp type gets encountered elsewhere the _typetable
	 * again provides help
         */
	int val = NULL;
	int addy = [_machine generateFreeAddress];
	[_typetable addType:addy withName:[status second]];
	[_machine pushDefinition:[[Hex new]setNumber:addy] with:[[Hex new]setNumber:val]];
	return 0;
}

- (int) parseDefinitionOfdefvar:(TupleInt*)sym and:(TupleInt*)val
{
	//TODO optional documentation string
	//TODO types of [var second] which is nto a form
	Hex *varhex = [[Hex new] ctorString:[sym second]];
	Hex *vargulf = [[Hex new] ctorInt:atoi([[val second] UTF8String])];

	//NSLOG4(@"vars = %d %d val=%@",[varhex number],[vargulf number],[val second]);

	Symbol *s2 = [_symboltable searchForHex: varhex ];
	int address;
	if (s2 == nil) 
		address = -1;
	else
		address = [[s2 address] number];
	Symbol *s;
	//generate a new Hex _address, if _symboltable does not contain hexnumber address
	if (address < 0) {//var does not already exist 
		NSLOG(@"defvarAtom : no address found");
		address = [_machine generateFreeAddress];
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ctype];
			break;
		case (const TYPE)itype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:itype];
			break;
		case (const TYPE)stype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:stype];
			break;
		case (const TYPE)ftype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			
			break;
		}

		[_symboltable addObject:s];

	} else {

		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ctype];
			break;
		case (const TYPE)itype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:itype];
			break;
		case (const TYPE)stype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:stype];
			break;
		case (const TYPE)ftype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		}
	}
	[self setLastSymbol:s];
	//add symbol
	[_machine pushDefinition:varhex with:vargulf];//FIXME value NSString to number

	return 0;
}

//Form in [val second] gets assigned to variable
- (int) parseDefinitionOfdefvarWithForm:(TupleInt*)sym and:(TupleInt*)val
{
	//TODO optional documentation string
	Hex *varhex = [[Hex new] ctorString:[sym second]];

	//NSLOG3(@"vars = %d val=%@",[varhex number],[val second]);

	Symbol *s2 = [_symboltable searchForHex: varhex ];
	int address;
	if (s2 == nil) 
		address = -1;
	else
		address = [[s2 address] number];
	Symbol *s;
	//generate a new Hex _address, if _symboltable does not contain hexnumber address
	if (address < 0) {//var does not already exist 
		NSLOG(@"defvarForm : no address found");
		address = [_machine generateFreeAddress];
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ctype];
			break;
		case (const TYPE)itype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:itype];
			break;
		case (const TYPE)stype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:stype];
			break;
		case (const TYPE)ftype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			
			break;
		}
		[_symboltable addObject:s];
	} else {
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ctype];
			break;
		case (const TYPE)itype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:itype];
			break;
		case (const TYPE)stype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:stype];
			break;
		case (const TYPE)ftype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		}

	}
	[self setLastSymbol:s];

	return 0;
}

- (int) parseDefinitionOfsetfq:(TupleInt*)sym and:(TupleInt*)val
{
	//TODO optional documentation string
	//TODO types of [var second] which is nto a form
	Hex *varhex = [[Hex new] ctorString:[sym second]];
	Hex *vargulf = [[Hex new] ctorInt:atoi([[val second] UTF8String])];

	//NSLOG4(@"vars = %d %d val=%@",[varhex number],[vargulf number],[val second]);

	Symbol* s2 = [_symboltable searchForHex: varhex ];
	int address;
	if (s2 == nil) 
		address = -1;
	else
		address = [[s2 address] number];
	Symbol *s;
	//generate a new Hex _address, if _symboltable does not contain hexnumber address
	if (address < 0) {//var does not already exist 
		NSLOG(@"setfqAtom : no address found");
		address = [_machine generateFreeAddress];
		NSLOG2(@"TYPE=%d",[self getTypeOfString:[val second]]);
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ctype];
			break;
		case (const TYPE)itype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:itype];
			break;
		case (const TYPE)stype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:stype];
			break;
		case (const TYPE)ftype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			
			break;
		}
		NSLOG2(@"s addr= %d",[[s address] number]);
		[_symboltable addObject:s];

	} else {
		NSLOG(@"setfqAtom : address found");
		NSLOG2(@"+++++++++++++++>%d",[self getTypeOfString:[val second]]);
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ctype];
			[_machine pushDefinition:varhex with:[[Hex alloc]ctorInt:atoi([[val second] UTF8String])]];
			break;
		case (const TYPE)itype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:itype];
			[_machine pushDefinition:varhex with:vargulf];
			break;
		case (const TYPE)stype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:stype];
			[_machine pushDefinition:varhex with:vargulf];
			break;
		case (const TYPE)ftype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ftype];
			[_machine pushDefinition:varhex with:vargulf];
			break;
		case (const TYPE)symtype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			[_machine pushDefinition:varhex with:vargulf];
			break;
		//default type is symtype
		default:
		case -1:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			[_machine pushDefinition:varhex with:vargulf];
			break;
		}
	}
	[self setLastSymbol:s];
	//add symbol

	return 0;

}

//Form in [val second] gets assigned to variable
- (int) parseDefinitionOfsetfqWithForm:(TupleInt*)sym and:(TupleInt*)val
{
	//TODO optional documentation string
	Hex *varhex = [[Hex new] ctorString:[sym second]];

	NSLOG3(@"setfq vars = %d val=%@",[varhex number],[val second]);

	Symbol *s2 = [_symboltable searchForHex: varhex ];
	int address;
	if (s2 == nil)
		address = -1;
	else
		[[s2 address] number];
	Symbol *s;
	//generate a new Hex _address, if _symboltable does not contain hexnumber address
	if (address < 0) {//var does not already exist 
		NSLOG(@"setfq Form : no address found");
		address = [_machine generateFreeAddress];
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ctype];
			break;
		case (const TYPE)itype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:itype];
			break;
		case (const TYPE)stype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:stype];
			break;
		case (const TYPE)ftype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			
			break;
		}
		[_symboltable addObject:s];
	} else {
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ctype];
			break;
		case (const TYPE)itype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:itype];
			break;
		case (const TYPE)stype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:stype];
			break;
		case (const TYPE)ftype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		}

	}
	[self setLastSymbol:s];
	return 0;
}

- (int) parseAssignment:(TupleInt*)status withValue:(TupleInt*)value
{

	[_symboltable set:[status second] value:[value second]];
	[_machine pushAssignment:[[Hex new] setNumber:[status second]] with:[[Hex new] setNumber:[value second]]];//FIXME value NSString etc to number	
	return 0;
}


- (int) setLastSymbol:(Symbol*)s
{

	_lastsymbol = s;
	return 0;

}

- (NSMutableArray*)splitForms:(NSString*)formstring
{
	//NOTE reversed formstring !
	NSMutableArray *array = [[NSMutableArray alloc] init];
	int idx = 0;
	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	char c;
	int nopen = 0;
	int nclosed = 0;
	while (idx < [formstring length]) {
		//NSLog(@"idx=%d c=%c",idx,[formstring characterAtIndex:idx]);
		//if ((c = [formstring characterAtIndex:idx]) == '`') {
			
		//} else 
		if ((c = [formstring characterAtIndex:idx]) == '(')
			nopen++;//NOTE formstring is reversed
			if (nopen == nclosed && nopen != 0 && nclosed != 0) {
				[s appendFormat:@"%c",c];
				Form *form = [[Form alloc] initWithString:s];
				//Form get formatted inherently with fomatLisp
				//in the above ctor
				NSLOG(@"Added form to array");
				[array addObject:form];
				s =[[NSMutableString alloc] initWithString: @""];
				nopen = nclosed = 0;
			}
		else if ((c = [formstring characterAtIndex:idx]) == ')') {
			nclosed++;//NOTE formstring is reversed
			[s appendFormat:@"%c",[formstring characterAtIndex:idx]];
		}
		else {
			[s appendFormat:@"%c",[formstring characterAtIndex:idx]];
		}
		idx++;
	 }

	//FIXME Lisp [fileName addStatus:HAVE_CLOSINGBRACE String:&st];
	NSLOG(@"Array of Forms done.");
	return array;

}
/*
- (int)hasSubForms:(NSString*)formstring
{
	NSMutableArray *array = [self splitForms:formstring];
	NSEnumerator *iter = [array objectEnumerator];
	Form *f;
	int n = -1;
	while (f = [iter nextObject])
		n++;
	if (n > -1)
		return n+2;//-1 and 0 
	else
		return -1;
}
*/
- (TupleInt*)hasSubForms:(NSString*)formstring
{
	NSMutableArray *array = [self splitForms:formstring];
	NSEnumerator *iter = [array objectEnumerator];
	Form *f;
	int n = -1;
	while (f = [iter nextObject]) {//TODO better implementation
		if ([formstring compare:[f string]] == 0)
			return [[TupleInt alloc] addFirst:-1 andSecond:nil];
		n++;
	}
	if (n > -1)
		//n+2, -1 and 0 
		return [[TupleInt alloc] addFirst:n+1 andSecond:array];
	else
		return [[TupleInt alloc] addFirst:-1 andSecond:nil];
}


- (int) parsePlus:(TupleInt*)ti
{					
	switch (((TYPE)[self getTypeOfString:[ti second]])) {
		
	case (const TYPE)ctype:{ //NOTE character (conversion from char to int - ascii)
		int a = atoi([[ti second] UTF8String]);
		NSString *s = [NSString stringWithFormat:@"%d",a];
		NSLOG2(@"converted ascii a=%@",s);
		[_machine pushOperatorPlusConstant:s];
		//TODO [self setLastSymbol:s2];
		return 0;
		break;
	}
	case (const TYPE)itype:{ //integer
		Hex* varhex = [[Hex alloc] ctorString:[ti second]];
		Symbol *s2 = [_symboltable searchForHex: varhex ];
		int address; 
		if (s2 == nil)
			address = -1;
		else
			address = [[s2 address] number];

		NSLOG2(@"address=%d",address);

		if (address > -1) //symbol exists
			[_machine pushOperatorPlusSymbol:[s2 address]];
		else				
			[_machine pushOperatorPlusConstant:[ti second]];
		[self setLastSymbol:s2];
		return 0;
		break;
	}
	case (const TYPE)ftype: //float
	//[_machine pushOperatorPlusConstant:[ti second]];//TODO foating point unit code
		break;
	case (const TYPE)symtype:
		default:{

			Hex* varhex = [[Hex alloc] ctorString:[ti second]];
			Symbol *s2 = [_symboltable searchForHex: varhex ];
			int address; 
			if (s2 == nil)
				address = -1;
			else
				address = [[s2 address] number];
			NSLOG2(@"address2=%d",address);
			if (address > -1) {//symbol exists
							
				[_machine pushOperatorPlusSymbol:[s2 address]];
				[self setLastSymbol:s2];
				return 0;
			} else {
				//symbol does not exist
				//thus can not be computed
				//TODO [self setLastSymbol:s2];
				NSLOG2(@"Invalid Types for + operator, TODO : no float type=%d", [self getTypeOfString:[ti second]]);
				//[form addError:
				return -1;
			}
			break;
		}
	}
	return -1;
}

- (int) parseMin:(TupleInt*)ti
{					
	switch (((TYPE)[self getTypeOfString:[ti second]])) {
		
	case (const TYPE)itype:{ //integer
		Hex* varhex = [[Hex alloc] ctorString:[ti second]];
		Symbol *s2 = [_symboltable searchForHex: varhex ];
		int address; 
		if (s2 == nil)
			address = -1;
		else
			address = [[s2 address] number];

		NSLOG2(@"address=%d",address);

		if (address > -1) //symbol exists
			[_machine pushOperatorMinusSymbol:[s2 address]];
		else				
			[_machine pushOperatorMinusConstant:[ti second]];
		return 0;
		break;
	}
	case (const TYPE)ftype: //float
	//[_machine pushOperatorMinusConstant:[ti second]];//TODO foating point unit code
		break;
	case (const TYPE)symtype:
		default:{
			Hex* varhex = [[Hex alloc] ctorString:[ti second]];
			Symbol *s2 = [_symboltable searchForHex: varhex ];
			int address;
			if (s2 == nil) 
				address = -1;
			else
				address = [[s2 address] number];
			if (address > -1) {//symbol exists
							
				[_machine pushOperatorMinusSymbol:[s2 address]];
				return 0;
			} else {
				//symbol does not exist
				//thus can not be computed
				NSLOG(@"Invalid Types for - operator, TODO : no float");
				//[form addError:
				return -1;
			}
			break;
		}
	}
	return -1;
}

- (int) parseMul:(TupleInt*)ti
{					
	switch (((TYPE)[self getTypeOfString:[ti second]])) {
		
	case (const TYPE)itype:{ //integer
		Hex* varhex = [[Hex alloc] ctorString:[ti second]];
		Symbol *s2 = [_symboltable searchForHex: varhex ];
		int address; 
		if (s2 == nil)
			address = -1;
		else
			address = [[s2 address] number];

		NSLOG2(@"address=%d",address);

		if (address > -1) //symbol exists
			[_machine pushOperatorMulSymbol:[s2 address]];
		else				
			[_machine pushOperatorMulConstant:[ti second]];
		return 0;
		break;
	}
	case (const TYPE)ftype: //float
	//[_machine pushOperatorMulConstant:[ti second]];//TODO foating point unit code
		break;
	case (const TYPE)symtype:
		default:{
			Hex* varhex = [[Hex alloc] ctorString:[ti second]];
			Symbol *s2 = [_symboltable searchForHex: varhex ];
			int address;
			if (s2 == nil) 
				address = -1;
			else
				address = [[s2 address] number];
			if (address > -1) {//symbol exists
							
				[_machine pushOperatorMulSymbol:[s2 address]];
			} else {
				//symbol does not exist
				//thus can not be computed
				NSLOG(@"Invalid Types for * operator, TODO : no float");
				//[form addError:
				return -1;
			}
			return 0;
			break;
		}
	}
	return -1;
}

-(int) skipWordAndWhiteSpace:(Form*)form withIndex:(int)idx
{
	//skip "first word"
	TupleInt *ti = [self grepWordOfLineParens:[form string] withIndex:idx];
	//skip prevailing whitespace
	NSLOG2(@"skip = %@",[ti second]);
	TupleInt *ti2 = [self skipWhiteSpace:[form string] withIndex:[ti first]];
	return [ti2 first];
}

-(int) skipFormAndWhiteSpace:(Form*)form withIndex:(int)idx
{
	int nopen = 0, nclosed = 0;
	int pidx = idx;

	if (idx > [form string])
		return -1;

	while (idx < [[form string] length]) {
		char c = [[form string] characterAtIndex:idx];
		if (c == '(')
			nopen ++;
		if (c == ')') {
			nclosed ++;
	
			if (nclosed == nopen && nopen > 0) {
				idx++;
				TupleInt *ti = [self skipWhiteSpace:[form string] withIndex:idx];
				return [ti first];
			}
		}
		//skip prevailing whitespace
		NSLOG2(@"skipForm = %c",c);
		idx++;
	}
	return idx;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ByteCodeMachine.h"

@implementation ByteCodeMachine

- (int) type
{
	return _type;
}

- (int)pushDefinition:(Hex*)hex {return -1;}
- (int)pushAssignment:(Hex*)hex {return -1;}
- (int)pushOperatorPlus:(Hex*)addr { return 1; }
- (int)pushOperatorPlusConstant:(NSString*)addr { return 1; }
- (int)pushOperatorPlusSymbol:(Hex*)hex { return -1; }
- (int)pushOperatorMinusConstant:(NSString*)addr { return 1; }
- (int)pushOperatorMinusSymbol:(Hex*)hex { return -1; }
- (int)pushOperatorPlusPlus:(Hex*)addr { return -1; }
- (int)pushOperatorPlusAssign:(Hex*)addr { return -1; }
- (int)pushOperatorMinus:(Hex*)addr { return -1; }
- (int)pushOperatorMinusMinus:(Hex*)addr { return -1; }
- (int)pushOperatorMinusAssign:(Hex*)addr { return -1; }
- (int)pushOperatorOr:(Hex*)addr { return -1; }
- (int)pushOperatorBitwiseOr:(Hex*)addr { return -1; }
- (int)pushOperatorExclusiveOr:(Hex*)addr { return -1; }
- (int)pushOperatorBitwiseExclusiveOr:(Hex*)addr { return -1; }
- (int)pushWhile:(Hex*)addr { return -1; }
- (int)pushLoopDefaultRegister { return -1; }
- (int)pushLoopGoto:(NSString*)l { return -1; }
- (int)pushIf:(Hex*)addr { return -1; }
- (int)pushLoadSymbol:(Hex*)hex { return -1; }
- (int)pushLoadConstant:(Hex*)hex { return -1; }
- (int)pushIfConstant:(int)addr { return -1; }
- (int)pushIfDefaultRegister { return -1; }
- (int)pushElse:(Hex*)addr { return -1; }
- (int)pushPreviousLabel { return -1; }
- (int)getLastLabel { return -1; }
- (int)generateFreeAddress {_freeaddycounter += 256*4; return _freeaddycounter;}
- (NSString*)generateFreeLabel {_freelabelcounter += 4; 
				NSMutableString *rs = [[NSMutableString alloc] initWithString:@"label"];
				[rs appendFormat: @"%d:",_freelabelcounter];
				return rs; }
@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#import "Enemy.h"
#include <pthread.h>
#include <assert.h>

void *routine(void *data) {
	int xx,yy;
	while (1) {
		xx += 10;
		[data setx:xx y:yy];
		[data setImage];
	}
							 
	 return NULL;						 
}

@implementation Enemy

- (id) ctor
{
	enemyImages[0] = [UIImage imageNamed:@"skeleton-down-1-32x32"];
	//playerImages[1] = [UIImage imageNamed:@"player-down-2-16x16"];
	//playerImages[2] = [UIImage imageNamed:@"player-down-3-16x16"];
	//playerImages[3] = [UIImage imageNamed:@"player-down-4-16x16"];
/*	pthread_attr_t attr;
	pthread_t pid;
	int ret;
	
	ret = pthread_attr_init(&attr);
	
	assert(!ret);

	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	
	assert(!ret);
	
	int er = pthread_create(&pid, &attr, &routine,self);
	
	ret = pthread_attr_destroy(&attr);
	
	assert(!ret);
	
	if (er != 0) {
		
	//raise error
		return nil;
		
	}
*/	
	return self;
}


- (UIImage*) render:(int)r
{
	switch (r) {
	case 1:
		return enemyImages[0];
		break;
	case 2:
		return enemyImages[0];
		break;
	case 3:
		return enemyImages[0];
		break;
	case 4:
		return enemyImages[0];
		break;
	default:
		return enemyImages[0];
			break;
	}
	//	}
	//}
	//return [UIImage imageNamed:@"tile-grass-1-16x16"];
}

- (void) setx:(int)xx y:(int)yy 
{
	x = xx;
	y = yy;
}

-(void) setImage
{
	enemyImages[0] = [UIImage imageNamed:@"KinkakuJi"];
	//[self setNeedsDisplay:YES];
}

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.


#import "EnemySubView.h"
#import "FirstViewController.h"

@implementation EnemySubView

- (id) alloc
{
	[super alloc];
	[self setNeedsDisplay:YES];

	return self;
}

- (id) initx:(int)xx y:(int)yy w:(int)ww h:(int)hh
{
	
	x = xx;
	y = yy;
	w = ww;
	h = hh;
	
	return self;
}

- (void)setx:(int)xx y:(int)yy
{
	x = xx;
	y = yy;
}

- (void)drawRect:(CGRect)rect
{
	int r  = rand();
	
	if (r < RAND_MAX/4) {
		x += 3;
		direction = @"right";
	}
	else if (r < RAND_MAX/2) {
		x -= 3;
		direction = @"left";
	}
	else if (r < RAND_MAX/4*3) {
		y += 3;
		direction = @"down";
	}
	else if (r < RAND_MAX) {
		y -= 3;
		direction = @"up";
	}
	else 
		x += 3;
	
	//x += 10;
	self.center = CGPointMake(x+IPADXOFFSET, y+IPADYOFFSET);
	if ([direction compare:@"left"] == 0)
		self.image = [UIImage imageNamed:@"skeleton-left-1-32x32"];//TODO put in class
	else if ([direction compare:@"right"] == 0)
		self.image = [UIImage imageNamed:@"skeleton-right-1-32x32"];
	else if ([direction compare:@"up"] == 0)
		self.image = [UIImage imageNamed:@"skeleton-up-1-32x32"];
	else if ([direction compare:@"down"] == 0)
		self.image = [UIImage imageNamed:@"skeleton-down-1-32x32"];
	struct timespec ts;
	ts.tv_sec = 0;
	ts.tv_nsec = 100000000;
	nanosleep(&ts,NULL);


	CGContextRef *context = UIGraphicsGetCurrentContext();
	
	
	NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(moveThread) object:nil];
	[thread start];
	
}

-(void)moveThread
{
	
		//enemysubview.center = CGPointMake(xoffset+IPADXOFFSET, yoffset+IPADYOFFSET);
		[self drawRect:CGRectMake((int)[self getx],(int)[self gety],16,16)];
		[self setNeedsDisplay];
	
}

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.


#import "FirstViewController.h"
#import "GameSubView.h"
#include <pthread.h>
#include <assert.h>
#include <stdlib.h>
#include <time.h>

#import "ArmLispCompiler.h"

@implementation FirstViewController
@synthesize imageView = mImageView;

@synthesize window;
@synthesize redButton,greenButton,blueButton,alphaButton,interactButton;

void *routine2(void *data) {
	int xx = 0,yy = 0;
	//struct timeval tv;
	struct timespec ts;
	//gettimeofday(&tv, NULL);
	ts.tv_sec = 0;
	ts.tv_nsec = 100000000;
	
	int t = 0;
	
	//while (1) 
	{
		//xx += 10;
		//[data setx:xx y:yy];
		//[data setImage];
		int r  = rand();
		
		if (r < RAND_MAX/4)
			xx += 32;
		else if (r < RAND_MAX/2)
			xx -= 32;
		else if (r < RAND_MAX/4*3)
			yy += 32;
		else if (r < RAND_MAX)
			yy -= 32;
		else {
			xx += 32;
		}

		//nanosleep(&ts,NULL);
		[data moveEnemyx:xx y:yy];
		//[data setNeedsReDisplay:YES];
		/*if ([data moveEnemyx:xx y:yy] == 0)
			continue;
		else {
			break;
		}*/

	}
	
	return NULL;						 
}



// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];

	fx = 0.0;
	nenemysubviews = 0;
	//self.imageView = [self.imageView initx:0 y:0 w:16 h:16 controller:self];
	//self.imageView = [self.imageView init];
	//[self.imageView initWithFrame:CGRectMake(0,0,16*16,16*16)];
	
	map = [[Map new] ctor];
	player = [[Player new] ctor];
	enemy = [[Enemy new] ctor];
	
	x = 0;
	y = 0;
	xoffset = x;
	yoffset = y;
	[[UIColor redColor] set];
	self.imageView.backgroundColor = [UIColor redColor];
	//self.imageView.backgroundColor = [UIColor redColor];
	
	int i = 0, j = 0;
	for ( ; i < 16; i++) {
		for ( ; j < 16; j++) {
			GameSubView* subview = [[GameSubView alloc] initWithFrame:CGRectMake(j*16+IPADXOFFSET, i*16+IPADYOFFSET, 16, 16)];
			
			//subview = [subview init:self.imageView];
			subview.image = [map renderx:j y:i];
			/*if (j == 7 && i == 7)
				subview.image = [player render:1];
			else if (j == 8 && i == 7)
				subview.image = [player render:2];
			else if (j == 7 && i == 8)
				subview.image = [player render:3];
			else if (j == 8 && i == 8)
				subview.image = [player render:4];
			*///else
			//	subview.image = [map renderx:j y:i];
			
			subview = [subview initx:j*16 y:i*16 w:16 h:16 controller:self];
			
			//[subview setNeedsReDisplay:YES];
			[self.imageView addSubview:subview];
			[self.imageView addSubviewToArray:subview];
			subviews[i][j] = subview;
			
		}
		j = 0;
	}

	GameSubView* subview = [[GameSubView alloc] initWithFrame:CGRectMake(7*16+IPADXOFFSET, 7*16+IPADYOFFSET, 32, 32)];
	subview = [subview initx:7*16+IPADXOFFSET y:7*16+IPADYOFFSET w:32 h:32 controller:self];
	subview.image = [player render:1];
	playersubviews[0] = subview;
	[self.imageView addSubview:subview];
	
	EnemySubView* subview2 = [[EnemySubView alloc] initWithFrame:CGRectMake(0*16+IPADXOFFSET, 0*16+IPADYOFFSET, 32, 32)];
	subview2 = [subview2 initx:0*16+IPADXOFFSET y:0*16+IPADYOFFSET w:32 h:32];
	subview2.image = [enemy render:1];
	enemysubviews[nenemysubviews++] = subview2;
	[self.imageView addSubview:subview2];
	

	
	//while () {
		/*
		struct timespec ts;
		//gettimeofday(&tv, NULL);
		ts.tv_sec = 0;
		ts.tv_nsec = 100000000;
		
	pthread_attr_t attr;
	pthread_t pid;
	int ret;
	
	ret = pthread_attr_init(&attr);
	
	assert(!ret);
	
	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	
	assert(!ret);
	
	int er = pthread_create(&pid, &attr, &routine2, self);
	
	ret = pthread_attr_destroy(&attr);
	
	assert(!ret);
	
	if (er != 0) {
		
		//raise error
		exit(0);
		
	}

	nanosleep(&ts,NULL);
	//}
		 */
	
//	NSString *filename = [[NSString alloc] initWithString:@"/Users/link/ios/examples/AllAboutImages1/AllAboutImages/test.lisp"];
	NSString *filename = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"lisp"];
	//NSString *filename = [[NSString alloc] initWithString:@"test.lisp"];


	
	ArmLispCompiler *armlispcompiler = [[ArmLispCompiler alloc] ctor:HAVE_MACHINE_ARMASM];
	[armlispcompiler compilablesource:filename];
	
	
	//NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(moveEnemies) object:nil];
	//[thread start];
	int ii = 0;
	while (ii < nenemysubviews) {
		enemysubviews[ii].center = CGPointMake(xoffset+IPADXOFFSET, yoffset+IPADYOFFSET);
		[enemysubviews[ii] drawRect:CGRectMake((int)[enemysubviews[ii] getx],(int)[enemysubviews[ii] gety],16,16)];
		[enemysubviews[ii] setNeedsDisplay];
		ii++;
	}
	
	
	
}

- (UIImageView*)getImageView
{
	return self.imageView;
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}


- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc. that aren't in use.
}


- (void)viewDidUnload
{
    self.imageView = nil;
    [super viewDidUnload];
}


- (void)dealloc
{
    [mImageView release];
    [super dealloc];
}

// MARK: -
// MARK: UI Actions
- (IBAction)contentModeChanged:(UISegmentedControl *)segmentedControl
{
	
	switch(segmentedControl.selectedSegmentIndex)
    {
			
		self.imageView.backgroundColor = [UIColor blackColor];
			
        case 0:{
			
            break;
		}
        case 1:
            //self.imageView.contentMode = UIViewContentModeScaleAspectFit;
			//subviews[0][0].contentMode = UIViewContentModeScaleAspectFit;
            break;
        case 2:
			//x -= 10;
			//y -= 10;
			//[self move];
            //self.imageView.contentMode = UIViewContentModeScaleAspectFill;
			//subviews[0][0].contentMode = UIViewContentModeScaleAspectFill;
            break;
    }
}

- (void)move
{
	self.imageView.backgroundColor = [UIColor blackColor];

	int i = 0, j = 0;
	for ( ; i < 16; i++) {
		for ( ; j < 16; j++) {
		
			//CGRect frame;
		//(	subviews[i][j]).image.frame.origin = CGPointMake(j*16+x, i*16+y);
		//frame.size.width = frame.size.height = 16;
		
			//subviews[i][j].center = CGPointMake(j*16+x, i*16+y);
			//subviews[i][j].center = CGPointMake(((int)[subviews[i][j] getx]+x), ((int)[subviews[i][j] gety]+y));
			//[subviews[i][j] setNeedsDisplay:YES];
		
		}
		j = 0;
	}
}


- (void) setx:(int)xx y:(int)yy
{
	x = xx;
	y = yy;
}

- (void)setImage:(UIImage*)img
{
	self.imageView.image = img;
}

//left
- (IBAction)doRedButton{ 
	[player setDirection:@"left"];
	playersubviews[0].image = [player render:1];
	//exit(0);
	int offset = 10;
	x += offset;
	self.imageView.backgroundColor = [UIColor blackColor]; 
	int i = 0, j = 0;
	for ( ; i < 16; i++) {
		for ( ; j < 16; j++) {
		
			//subviews[i][j].image = [map renderx:j y:i];
			subviews[i][j].center = CGPointMake(j*16+x+IPADXOFFSET, i*16+y+IPADYOFFSET);
			
		}
		j = 0;
	}
	
	//for ( ; i < 1000000; i++) {
	//	enemysubview.image = [enemy render:1];
	//xoffset += 32;
	int ii = 0;
	while (ii < nenemysubviews) {
		int ex = [enemysubviews[ii] getx];
		int ey = [enemysubviews[ii] gety];
		//enemysubviews[ii].center = CGPointMake(ex-x+IPADXOFFSET,ey+IPADYOFFSET);
		[enemysubviews[ii] setNeedsDisplay];
		[enemysubviews[ii] setx:ex+offset y:ey];
		ii++;
	}
		//[self.imageView setNeedsDisplay:YES];
		//[enemysubviews[0][0] setNeedsDisplay:YES];
	//}
	//[enemysubview setNeedsDisplay:YES];
}

//right
- (IBAction)doGreenButton{
	[player setDirection:@"right"];
	playersubviews[0].image = [player render:1];
	//exit(0);
	int offset = 10;
	x -= offset;
	self.imageView.backgroundColor = [UIColor redColor]; 
	int i = 0, j = 0;
	for ( ; i < 16; i++) {
		for ( ; j < 16; j++) {
			
			subviews[i][j].center = CGPointMake(j*16+x+IPADXOFFSET, i*16+y+IPADYOFFSET);
			
		}
		j = 0;
	}
	int ii = 0;
	while (ii < nenemysubviews) {
		int ex = [enemysubviews[ii] getx];
		int ey = [enemysubviews[ii] gety];
		//enemysubviews[ii].center = CGPointMake(ex+offset+IPADXOFFSET,ey+IPADYOFFSET);
		[enemysubviews[ii] setNeedsDisplay];
		[enemysubviews[ii] setx:ex-offset y:ey];
		ii++;
	}
}
//move up
- (IBAction)doBlueButton{ 
	[player setDirection:@"up"];
	playersubviews[0].image = [player render:1];
	//exit(0);
	int offset = 10;
	y += offset;
	self.imageView.backgroundColor = [UIColor redColor]; 
	int i = 0, j = 0;
	for ( ; i < 16; i++) {
		for ( ; j < 16; j++) {
			
			subviews[i][j].center = CGPointMake(j*16+x+IPADXOFFSET, i*16+y+IPADYOFFSET);
			
		}
		j = 0;
	}
	int ii = 0;
	while (ii < nenemysubviews) {
		int ex = [enemysubviews[ii] getx];
		int ey = [enemysubviews[ii] gety];
		//enemysubviews[ii].center = CGPointMake(ex+offset+IPADXOFFSET,ey+IPADYOFFSET);
		[enemysubviews[ii] setNeedsDisplay];
		[enemysubviews[ii] setx:ex y:ey+offset];
		ii++;
	}
}
//move down
- (IBAction)doAlphaButton{ 
	[player setDirection:@"down"];
	playersubviews[0].image = [player render:1];
	//exit(0);
	int offset = 10;
	y -= offset;
	self.imageView.backgroundColor = [UIColor redColor]; 
	int i = 0, j = 0;
	for ( ; i < 16; i++) {
		for ( ; j < 16; j++) {
			
			subviews[i][j].center = CGPointMake(j*16+x+IPADXOFFSET, i*16+y+IPADYOFFSET);
			
		}
		j = 0;
	}
	int ii = 0;
	while (ii < nenemysubviews) {
		int ex = [enemysubviews[ii] getx];
		int ey = [enemysubviews[ii] gety];
		//enemysubviews[ii].center = CGPointMake(ex+offset+IPADXOFFSET,ey+IPADYOFFSET);
		[enemysubviews[ii] setNeedsDisplay];
		[enemysubviews[ii] setx:ex y:ey-offset];
		ii++;
	}
}


//interact
- (IBAction)doInteractButton
{
	int ii = 0;
	while (ii < nenemysubviews) {
		
		int xx = [enemysubviews[ii] getx];
		int yy = [enemysubviews[ii] gety];
		int px = [playersubviews[0] getx];
		int py = [playersubviews[0] gety];
		if (abs(xx - px) < 100 && abs(yy - py) < 300)
				  [self interact];
		ii++;	
	}
}

- (void)interact
{
	exit(0);
}

-(void)moveEnemies
{
	NSRunLoop* loop = [NSRunLoop currentRunLoop];
	/*
	CFRunLoopObserverContext *context = (0,self,NULL,NULL,NULL);
	
	CFRunLoopObserverRef *observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, &myRunLoopObserver, &context);
	if (observer) {
		
		CFRunLoopRef cfLoop = [loop getCFRunLoop];
		CFRunLoopAddObserver(cfLoop, observer, kCFRunLoopDefaultMode);
	}
		
	[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(doFireTimer:) userInfo:nil repeats:YES];
	*/
	
	NSDate *futureDate = [NSDate dateWithTimeIntervalSinceNow:1];
	NSTimer *timer = [[NSTimer alloc] initWithFireDate:futureDate interval:0.1 target:self selector:@selector(myDoFireTimer:) userInfo:nil repeats:YES];
	
	[loop addTimer:timer forMode:NSDefaultRunLoopMode];
	
	int count = 1;
	do {
		
	//xoffset += 32;
	//yoffset += 32;
		int ii = 0;
		while (ii < nenemysubviews) {
			enemysubviews[ii].center = CGPointMake(xoffset+IPADXOFFSET, yoffset+IPADYOFFSET);
			[enemysubviews[ii] drawRect:CGRectMake((int)[enemysubviews[ii] getx],(int)[enemysubviews[ii] gety],16,16)];
			[enemysubviews[ii] setNeedsDisplay];
			ii++;
		}
	//	struct timespec ts;
	//	//gettimeofday(&tv, NULL);
	//	ts.tv_sec = 0;
	//	ts.tv_nsec = 5000000;
		//nanosleep(&ts, NULL);
		
		//[loop runUntilDate:futureDate];//[NSDate dateWithTimeIntervalSinceNow:1]];
	//sleep(1);
	} while (count--);
}

- (int)moveEnemyx:(int)xx y:(int)yy 
{ 
	//exit(0);
	//fx += 0.1;
	
	/*int r  = rand();
	
	if (r < RAND_MAX/4)
		x += 1;
	else if (r < RAND_MAX/2)
		x -= 1;
	else if (r < RAND_MAX/4*3)
		y += 1;
	else if (r < RAND_MAX)
		y -= 1;
	*/
	//enemysubviews[0][0].image = [map renderx:j y:i];
	//xoffset += xx;
	//yoffset += yy;
	int ii = 0;
	while (ii < nenemysubviews) {
		enemysubviews[ii].center = CGPointMake(xoffset+IPADXOFFSET, yoffset+IPADYOFFSET);
	//sleep(1);
		ii++;
	}
	return 0;
/*	GameSubView* subview2 = [[GameSubView alloc] initWithFrame:CGRectMake(0*16+xx+IPADXOFFSET, 0*16+yy+IPADYOFFSET, 32, 32)];
	subview2 = [subview2 initx:0*16+xx+IPADXOFFSET y:0*16+yy+IPADYOFFSET w:32 h:32 controller:self];
	subview2.image = [enemy render:1];
	[enemysubview dealloc];
	enemysubview = subview2;
	[self.imageView addSubview:subview2];
*/	//[enemysubview setNeedsDisplay:YES];
	
}

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.


#import "GameSubView.h"
#import "FirstViewController.h"

@implementation GameSubView

//@synthesize redButton,greenButton,blueButton;//The GameView is the first responder for these buttons


- (id) alloc
{
	[super alloc];
	[self setNeedsDisplay:YES];

	return self;
}

- (id) initx:(int)xx y:(int)yy w:(int)ww h:(int)hh controller:(UIViewController*)p
{

	controller = p;
	
	x = xx;
	y = yy;
	w = ww;
	h = hh;
	/*UIImage *image = [UIImage imageNamed:@"KinkakuJi"];
	UIImage *image2 = [UIImage imageNamed:@"t16tiles"];
	self.animationImages = [NSArray new];
	[self.animationImages addObject:image];
	[self.animationImages addObject:image2];
	
	*///map = [[ Map alloc] ctor];
	
	return self;
}

- (void)drawRect:(CGRect)rect
{
	x += 4;
	self.center = CGPointMake(x+IPADXOFFSET, y+IPADYOFFSET);
	
		struct timespec ts;
	//	//gettimeofday(&tv, NULL);
		ts.tv_sec = 0;
		ts.tv_nsec = 500000000;
	nanosleep(&ts,NULL);
	
	//sleep(1);

	//[self setNeedsDisplay];

	CGContextRef *context = UIGraphicsGetCurrentContext();
	//UIImage *image = [UIImage imageNamed:@""];
	//self.image = image;
	//[image drawInRect:rect];
	//self.image = image;
	//x = 100;
	//self.center = CGPointMake(x+IPADXOFFSET, y+IPADYOFFSET);
	//[self setNeedsDisplay];
//	[[UIColor redColor] set];
//	self.view.backgroundColor = [UIColor redColor];
	//GSRectfill(0,0,100,100);
	//self.center = CGPointMake(100,100);
	//[((FirstViewController*) controller) doRedButton];
	
	NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(moveEnemies2) object:nil];
	[thread start];
	
}

-(void)moveEnemies2
{
	
		
		//enemysubview.center = CGPointMake(xoffset+IPADXOFFSET, yoffset+IPADYOFFSET);
		[self drawRect:CGRectMake((int)[self getx],(int)[self gety],16,16)];
		[self setNeedsDisplay];
	
}


- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//	UITouch *touch = [[event allTouches] anyObject];
//	CGPoint touchLocation = [touch locationInView:self.view];//TODO self.view
	
	//if (CGRectContainsPoint(self.window.frame, touchLocation)) {
	//x += 10;
	//y += 10;
	
	[((FirstViewController*) controller) setx:x y:y];
	[((FirstViewController*) controller) move];
	//dragging = YES;
	//}
	
	//UIImage *image = [UIImage imageNamed:@"t16tiles"];//[map render];
	//[controller setImage:image];
	
	
	//[controller getImageView].backgroundColor = [UIColor blackColor];
	//self.imageView.clipsToBounds = YES;
	
	//self.imageView.image = image;
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{}

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{}


- (int) getx
{
	return x;
}

-(int) gety
{
	return y;
}

//GameView is first responder

- (void)doRedButton{ /*exit(0);*/
	//x -= 10;
	//[((FirstViewController*) controller) doRedButton]; 
	//self.center = CGPointMake(0,0);
	//UIImageView* view = [controller getImageView];
	//view.center = CGPointMake(0, 0);
	//[self setNeedsDisplay:YES];
	
}

- (void)foo{ /*exit(0);*/
	//x -= 10;
	//[((FirstViewController*) controller) doRedButton]; 
	//self.center = CGPointMake(0,0);
	//UIImageView* view = [controller getImageView];
	//view.center = CGPointMake(0, 0);
	//[self setNeedsDisplay:YES];
	
}


//- (IBAction)doRedButton{ /*exit(0);*/
/*	//x -= 10;
	//[((FirstViewController*) controller) doRedButton]; 
	self.center = CGPointMake(0,0);
	//UIImageView* view = [controller getImageView];
	//view.center = CGPointMake(0, 0);
	//[self setNeedsDisplay:YES];

}*/
/*- (IBAction)doGreenButton{  
	x += 10;
	self.center = CGPointMake(x, y);	
}
- (IBAction)doBlueButton{
	y += 10;
	self.center = CGPointMake(x,y); 
}*/

/*
-(void) keyDown: (NSEvent *)event
{
	//NSLog(@"%d %@",[event keyCode], [event characters]);
	
	switch ([[event characters] characterAtIndex:0])
	{
		case 'a':
			break;
	}
}*/

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.


#import "GameView.h"
#import "GameSubView.h"
#import "FirstViewController.h"

@implementation GameView

@synthesize redButton,greenButton,blueButton;//The GameView is the first responder for these buttons

- (id) alloc
{
	[super alloc];
	[self setNeedsDisplay:YES];
	
	return self;
}

- (id) init
{
	//[super alloc];
	//[self initWithFrame:CGRectMake(0,0,16*16,16*16)];
	
	//controller = p;
	
	x = 0;
	y = 0;
	w = 16*16;
	h = 16*16;
	
	[[UIColor redColor] set];
	self.backgroundColor = [UIColor redColor];
	
	UIImage *image = [UIImage imageNamed:@"KinkakuJi"];
	self.image = image;
	//UIImage *image2 = [UIImage imageNamed:@"t16tiles"];
	//self.animationImages = [NSArray new];
	//[self.animationImages addObject:image];
	//[self.animationImages addObject:image2];
	
	//map = [[ Map alloc] ctor];
	
}
- (void)drawRect:(CGRect)rect
{
	CGContextRef *context = UIGraphicsGetCurrentContext();
	
	[[UIColor redColor] set];
	self.backgroundColor = [UIColor redColor];

//	CGContextRef *context = UIGraphicsGetCurrentContext();
	UIImage *image = [UIImage imageNamed:@"KinkakuJi"];
	self.image = image;
	
	//UIImage *image = [UIImage imageNamed:@"KinkakuJi"];
	//[image drawInRect:rect];
	//[self setNeedsDisplay:YES];
	//GSRectfill(0,0,100,100);
	
	//[((FirstViewController*) controller) doRedButton];
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//	UITouch *touch = [[event allTouches] anyObject];
//	CGPoint touchLocation = [touch locationInView:self.view];//TODO self.view
	
	//if (CGRectContainsPoint(self.window.frame, touchLocation)) {
	//x += 10;
	//y += 10;
	
	//[((FirstViewController*) controller) setx:x y:y];
	//[((FirstViewController*) controller) move];
	//dragging = YES;
	//}
	
	//UIImage *image = [UIImage imageNamed:@"t16tiles"];//[map render];
	//[controller setImage:image];
	
	
	//[controller getImageView].backgroundColor = [UIColor blackColor];
	//self.imageView.clipsToBounds = YES;
	
	//self.imageView.image = image;
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{}

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{}


- (int) getx
{
	return x;
}

-(int) gety
{
	return y;
}

//GameView is first responder
- (IBAction)doRedButton{ 
	
	//[self setNeedsDisplay:YES];
	
	int i = 0, j = 0;
	for ( ; i < 16; i++) {
		for ( ; j < 16; j++) {
			
			//CGRect frame;
			//(	subviews[i][j]).image.frame.origin = CGPointMake(j*16+x, i*16+y);
			//frame.size.width = frame.size.height = 16;
			
			subviews[i][j].center = CGPointMake(0,0);//j*16+x, i*16+y);
			[subviews[i][j] initWithImage: [UIImage imageNamed:@"tile-grass-3-16x16"]];
			[subviews[i][j] setNeedsDisplay:YES];
			//subviews[i][j].center = CGPointMake(((int)[subviews[i][j] getx]+x), ((int)[subviews[i][j] gety]+y));
			//[subviews[i][j] setNeedsDisplay:YES];
			
		}
		j = 0;
	}
	
	//x -= 10;
	
	//[((FirstViewController*) controller) doRedButton]; 
	//self.center = CGPointMake(0,0);
	
	//UIImageView* view = [controller getImageView];
	//view.center = CGPointMake(0, 0);
	//[self setNeedsDisplay:YES];
	/*
	NSArray *array = [self subviews];
		 
	NSEnumerator *e = [array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		//object.center = CGPointMake(0,0);
		//if ([self isKindOfClass:[GameSubView class]]) {
			//[((GameSubView*) object) foo];
		//[object.center = CGPointMake(0, 0)];
		//}
	}*/
}
-(void)addSubviewToArray:(GameSubView*)v
{
	subviews[((int)[v getx])%16][((int)[v gety])%16] = v;
}

- (IBAction)doGreenButton{  
	//x += 10;
	//self.center = CGPointMake(x, y);	
}
- (IBAction)doBlueButton{
	//y += 10;
	//self.center = CGPointMake(x,y); 
}

/*
-(void) keyDown: (NSEvent *)event
{
	//NSLog(@"%d %@",[event keyCode], [event characters]);
	
	switch ([[event characters] characterAtIndex:0])
	{
		case 'a':
			break;
	}
}*/

@end
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.


#import <UIKit/UIKit.h>

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#import "Map.h"


@implementation Map

- (id) ctor
{
	w = 16;
	h = 16;
	//[mapImages addObject: [UIImage imageNamed:@"tile-grass-1-16x16"]];
	mapImages[0] = [UIImage imageNamed:@"tile-grass-1-16x16"];
	mapImages[1] = [UIImage imageNamed:@"tile-grass-2-16x16"];
	mapImages[2] = [UIImage imageNamed:@"tile-grass-3-16x16"];
	
	return self;
}

- (UIImage*) renderx:(int)xx y:(int)yy
{
	switch (((int)map1[yy][xx])) {
	case 1:
		return mapImages[0];
		break;
	case 2:
		return mapImages[1];
		break;
	case 3:
		return mapImages[2];
		break;
	default:
		return mapImages[0];
			break;
	}
	//	}
	//}
	//return [UIImage imageNamed:@"tile-grass-1-16x16"];
}

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#import "Player.h"


@implementation Player

- (id) ctor
{
	direction = @"down";
	playerImages[0] = [UIImage imageNamed:@"player-left-1-32x32"];
	playerImages[1] = [UIImage imageNamed:@"player-right-1-32x32"];
	playerImages[2] = [UIImage imageNamed:@"player-up-1-32x32"];
	playerImages[3] = [UIImage imageNamed:@"player-down-1-32x32"];
	
	return self;
}

-(void) setDirection:(NSString*)d
{
	direction = d;
}

- (UIImage*) render:(int)r
{
	
	if ([direction compare:@"left"] == 0)
		return playerImages[0];
	else if ([direction compare:@"right"] == 0)
		return playerImages[1];
	else if ([direction compare:@"up"] == 0)
		return playerImages[2];
	else if ([direction compare:@"down"] == 0)
		return playerImages[3];
	else {
		return playerImages[0];
	}

/*	switch (r) {
	case 1:
		return playerImages[0];
		break;
	case 2:
		return playerImages[0];
		break;
	case 3:
		return playerImages[0];
		break;
	case 4:
		return playerImages[0];
		break;
	default:
		return playerImages[0];
			break;
	}
	//	}
	//}
	//return [UIImage imageNamed:@"tile-grass-1-16x16"];
*/
}

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
// Copyright (c) 2011 iOSDeveloperZone.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.


#import "SecondViewController.h"


@implementation SecondViewController

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
}
*/

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}


- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc. that aren't in use.
}


- (void)viewDidUnload
{
    [super viewDidUnload];

    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc
{
    [super dealloc];
}

@end
/*
 Copyright (C) 2013 Johan Ceuppens
 
 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/*
#import "ThreeButtonsAppDelegate.h"


@implementation ThreeButtonsAppDelegate

@synthesize window;
@synthesize redButton,greenButton,blueButton;

- (IBAction)doRedButton{ window.backgroundColor = [UIColor redColor];}
- (IBAction)doGreenButton{window.backgroundColor = [UIColor greenColor];}
- (IBAction)doBlueButton{window.backgroundColor = [UIColor blueColor];}

@end
*/



\end{verbatim}
\end{mylisting}


\section{Internal Arm systems Lisp Compiler (with Objective C insertion)}

\begin{mylisting2}
\begin{verbatim}

/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "ByteCodeMachine.h"
#import "Hex.h"
#import "arm-lisp-config.h"

@interface NesAssemblerMachine : ByteCodeMachine {

}

- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2;
- (int)pushAssignment:(Hex*)hex with:(Hex*)hex2;
- (int)pushOperatorPlus:(Hex*)addr;
- (int)pushOperatorPlusConstant:(NSString*)val;
- (int)pushOperatorPlusSymbol:(Hex*)hex;
- (int)pushOperatorMulConstant:(NSString*)val;
- (int)pushOperatorMulSymbol:(Hex*)hex;
- (int)pushOperatorPlusPlus:(Hex*)addr;
- (int)pushOperatorPlusAssign:(Hex*)addr andAddress:(Hex*)addr2;
- (int)pushOperatorMinus:(Hex*)addr;
- (int)pushOperatorMinusMinus:(Hex*)addr;
- (int)pushOperatorMinusAssign:(Hex*)addr andAddress:(Hex*)addr2;
- (int)pushOperatorOr:(Hex*)addr;
- (int)pushOperatorBitwiseOr:(Hex*)addr;
- (int)pushOperatorAnd:(Hex*)addr;
- (int)pushOperatorBitwiseAnd:(Hex*)addr;
- (int)pushIf:(Hex*)addr;
- (int)pushElse:(Hex*)addr;
- (int)pushPreviousLabel;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "ByteCodeMachine.h"
#import "Hex.h"

@interface ArmAssemblerMachine : ByteCodeMachine {

}

- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2;
- (int)pushOperatorPlusConstant:(NSString*)val;
- (int)pushOperatorPlusSymbol:(Hex*)addr;
- (int)pushOperatorMinusConstant:(NSString*)val;
- (int)pushOperatorMinusSymbol:(Hex*)addr;
- (int)pushOperatorMulConstant:(NSString*)val;
- (int)pushOperatorMulSymbol:(Hex*)addr;
- (int)pushIf:(Hex*)hex;
- (int)pushLoopDefaultRegister;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import <Foundation/Foundation.h>
#import "Compiler.h"
#import "ClassLocator.h"
#import "FileName.h"

typedef struct RType { int id; NSString *rtypestring; } RType;

//file status & error ints 
enum { SUBCOMPILENOT = -2,
		SUBCOMPILENOMKSTEMP = -3,
		SUBCOMPILENOFDOPEN = -4,
		SUBCOMPILECANNOTFORK = -5,
		SUBCOMPILECANNOTLOCK = -6,
		SUBCOMPILECANNOTUNLOCK = -7,
		SUBCOMPILEINVALIDRETURNTYPE = -8,
		SUBCOMPILEINVALIDFUNCNAME = -9,
		SUBCOMPILEINVALIDARGS = -10,
		SUBCOMPILEINVALIDFUNCDEF = -11,

		OBJCHEADERCOMPILE = -100,
		OBJCSOURCECOMPILE = -101,
		PURECCOMPILE = -102,
};

@interface ArmCompilerBase : Compiler {

	ClassLocator *_classLocator;
	
}

- (int) scanObjCMethodDeclarationIn:(FileName*)fileName withIndex:(int*)i;
- (int) scanDeclarationForType:(NSString*)pstr withIndex:(int*)i returns:(struct RType*)rType;
- (int) scanDeclarationForFuncName:(NSString*)pstr withIndex:(int*)i returns:(NSString*)rName;
- (int) scanDeclarationForArgs:(NSString*)pstr withIndex:(int*)i returns:(NSMutableArray*)rArgs;

- (int) writeDeclarationWithReturnTypeToHeader:(struct RType*)returnType withFuncName:(NSString*)funcName andArgs:(NSMutableArray*)Args onfno:(int)fno;
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import <Foundation/Foundation.h>
#import "Compiler.h"
#import "FNString.h"
#import "ArmScanner.h"
#import "ParseString.h"

@interface ArmCompiler : Compiler {

	ArmScanner *_armScanner;
	
}

enum {
	NOTFOUND = -1, 
};

- (void)compile:(FNString*)fileName;
- (void)scanFile:(FNString*)fileName;
- (int)scanFileRec:(FNString*)fileName;
- (int)compilable:(FNString*)fileName;
- (int)compilableheader:(FNString*)fileName;
- (int)compilablesource:(FNString*)fileName;
- (int) searchFor:(NSString*)fileBuffer char:(unichar)c startingAt:(int)startidx numberOfSkips:(int*)skips;
- (int) searchFor:(NSString*)fileBuffer char:(unichar)c startingAt:(int)startidx;
- (int) searchFor:(NSString*)fileBuffer string:(NSString*)s startingAt:(int)startidx;

- (int*)compilableInterfaceMethod:(NSString *)methodstr;
- (int*)compilableCheckReturnType:(NSString*)methodstr;
- (int*)compilableCheckFunctionName:(NSString*)methodstrpart;
- (int*)compilableCheckFunctionArgName:(NSString*)methodstrpart;
- (int*)compilableCheckFunctionArgs:(NSString*)methodstrpart;

- (NSString*)reverse:(NSString*)str;


@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import <Foundation/Foundation.h>
#import "arm-lisp-config.h"
#import "ArmCompiler.h"
#import "TypeTable.h"
#import "SymbolTable.h"
#import "OperatorTable.h"
#import "ByteCodeMachine.h"

enum {
	NOENDOFIMPLEMENTATION = -2, 
	NOCLOSINGBRACE = -3,

};

enum {
	HAVE_ENDOFIMPLEMENTATION = 2,
	HAVE_OPENINGBRACE = 3,
	HAVE_CLOSINGBRACE = 4,
	HAVE_FILEPARSED = 5,
	HAVE_DEFINITION = 6,
	HAVE_OPERATOR = 7,
	HAVE_IF = 8,
	HAVE_ELSE = 9,
};

enum {
	SYMBOL_ASSIGNMENT = '=',
};

@interface ArmLispCompiler : ArmCompiler {

	ByteCodeMachine* _machine;

	OperatorTable *_operatortable;
	SymbolTable* _symboltable;
	TypeTable *_typetable;
	TupleInt *_parsetreestatus;

	Symbol* _lastsymbol;
}

- (ArmLispCompiler*)ctor:(MACHINETYPE)i;
- (int)grepLines:(NSString *)fileName; 
- (TupleInt*)grepWord:(FNString *)fileName withIndex:(int)idx;
- (TupleInt*)getRestOfForm:(NSString*)formstring withIndex:(int)idx;
- (TupleInt*) parsehexandset:(int)h; 
- (TYPE)checkTypeOf:(Symbol*)s and:(TYPE)t;
- (TYPE)getTypeOf:(NSString*)s;

- (int)compilablesource:(NSString*)fileName;
- (int) parseFile:(FNString*)fileName withIndex:(int)idx; 
- (int) parseForms:(FNString*)fileName withIndex:(int)idx; 
- (NSMutableArray*)splitForms:(NSString*)line;
- (int) parseLineForAssignment:(NSString*)line;
- (int) parseFormForDefinition:(Form*)form;
- (int) parseFormForOperator:(Form*)form;
- (int) parsePlus:(TupleInt*)ti;
- (int) parseLineForAssignmentWithOperator:(NSString*)line;
- (int) parseForm:(FNString*)fileName withIndex:(int)idx;
- (int) parseDefinitionOfdeftype:(TupleInt*)status;
- (int) parseDefinitionOfdefvar:(TupleInt*)status hex:(Hex*)hex;
- (int) parseDefinitionOfdefvarWithForm:(TupleInt*)sym and:(TupleInt*)val;
- (int) parseDefinitionOfsetq:(TupleInt*)status hex:(Hex*)hex;
- (int) parseDefinitionOfsetf:(TupleInt*)status hex:(Hex*)hex;
- (int) parseOperator:(NSString*)op withAddress:(Hex*)addr;
- (int) parseOperator:(NSString*)op withAddress:(Hex*)addr andAddress:(Hex*)addr2;
- (int)parseOperator:(NSString*)op form:(Form*)form;
- (int) parseAssignment:(TupleInt*)status withOp:(TupleInt*)value;

- (int) setLastSymbol:(Symbol*)s;

- (int)hasSubForms:(NSString*)formstring;
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
//
//  Created by link on 25/10/12.
//

#ifndef ARMLISP_CONFIG_H_
#define ARMLISP_CONFIG_H_

/*
 * This is a TypeName class as seen in libobjcgbarm
 */

#import <Foundation/Foundation.h>

#define _ARM 1

#define _ARM7 0
#define _ARM7_GBA 1 
#define _ARM9 1
#define _ARM10 0
#define _ARM11 0

//GFX
#if (_ARM7 || _ARM9)
#define _ARMSCREENWIDTH 240
#define _ARMSCREENHEIGHT 160
#else
#define _ARMSCREENWIDTH 240
#define _ARMSCREENHEIGHT 160
#endif

#define _DEBUG 1

void NSLOG(void*x);
void NSLOG2(void*x,void*y);
void NSLOG3(void*x,void*y,void*z);
void NSLOG4(void*x,void*y,void*z,void*xx);
void NSLOG5(void*x,void*y,void*z,void*xx,void*yy);
void NSLOG6(void*x,void*y,void*z,void*xx,void*yy,void*zz);
void NSLOG7(void*x,void*y,void*z,void*xx,void*yy,void*zz,void*xxx);
#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

////////////NOTE: NOT USED !

#import <Foundation/Foundation.h>
//////#include "FileName.h"

@interface ArmLispScanner : NSObject {
	
}

- (ArmLispScanner*)ctor;
////////- (int)scanFile:(FileName*)filename withCompiler:(Compiler*)compiler;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#include "FNString.h"
///////#import "Scanner.h"
#import "Compiler.h"

@interface ArmScanner : NSObject { ///////Scanner {
	
}

- (int)scanFile:(FNString*)filename withCompiler:(Compiler*)compiler;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import <Foundation/Foundation.h>
#import "ArmSubScanner.h"
#import "ArmCompiler.h"
#import "ClassLocator.h"
#import "ErrorSubCompiler.h"

typedef struct RType { int id; NSString *rtypestring; } RType;

//auto- C in objC compiler or other langs with output to elf
@interface ArmSubCompiler : ArmCompiler {

	ArmSubScanner *_armSubScanner;
	NSString *_compilerShellCommand;
	ClassLocator *_classLocator;

	ErrorSubCompiler *_errorsubcompiler;
}

- (ArmSubCompiler*)ctor:(NSString*)command;
- (void)erroradd:(int)ei;
- (int)errorset;
- (void)compile:(FNString*)fileName;//override for other compiler command
- (void)scanFile:(FNString*)fileName;
- (int)scanFileRec:(FNString*)fileName;
- (int)subCompilable:(FNString*)fileName;
- (int)subCompilableObjCSourceFile:(FNString*)fileName;
//pure C in method definitions ->
- (int)subCompilableRec:(FNString*)pstr withIndex:(int)idx;
//non-pure C but objC in method definitions ->
- (int)compileRec:(FNString*)fileName;
- (int)compileObjC:(int)idx;

- (int)compilablesource:(FNString*)fileName;

- (int) scanObjCMethodDeclarationIn:(FNString*)pstr withIndex:(int)idx fino:(int)fno;
- (int) scanDeclarationForType:(NSString*)pstr withIndex:(int)idx returns:(struct RType*)rType;
- (int) scanDeclarationForFuncName:(NSString*)pstr withIndex:(int)idx returns:(NSString*)rName;
- (int) scanDeclarationForArgs:(NSString*)pstr withIndex:(int)idx returns:(NSMutableArray*)rArgs;

- (int) writeDeclarationWithReturnTypeToHeader:(struct RType*)returnType withFuncName:(NSString*)funcName andArgs:(NSMutableArray*)Args onfno:(int)fno;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "FNString.h"
#import "Compiler.h"
#import "ArmScanner.h"

@interface ArmSubScanner : ArmScanner {

}

- (int)scanFile:(FNString*)filename withCompiler:(Compiler*)compiler;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "Hex.h"
typedef int MACHINETYPE;

enum {
	HAVE_MACHINE_JAVA = 2,
	HAVE_MACHINE_ARMASM = 3,
	HAVE_MACHINE_6502ASM = 4,
	HAVE_MACHINE_ARMBYTE = 5,
	HAVE_MACHINE_6502BYTE = 6,
};

@interface ByteCodeMachine : NSObject {

	int _type;
	NSMutableArray* _bytecode;//strings
	int _freeaddycounter;//for storing variables
	int _freelabelcounter;
}

- (int)type;
- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2;
- (int)pushAssignment:(Hex*)hex with:(Hex*)hex2;
- (int)pushOperatorPlus:(Hex*)addr;
- (int)pushOperatorPlusConstant:(NSString*)val;
- (int)pushOperatorPlusSymbol:(Hex*)addr;
- (int)pushOperatorMinusConstant:(NSString*)val;
- (int)pushOperatorMinusSymbol:(Hex*)addr;
- (int)pushOperatorMulConstant:(NSString*)val;
- (int)pushOperatorMulSymbol:(Hex*)addr;
- (int)pushOperatorPlusPlus:(Hex*)addr;
- (int)pushOperatorPlusAssign:(Hex*)addr andAddress:(Hex*)addr2;
- (int)pushOperatorMinus:(Hex*)addr;
- (int)pushOperatorMinusMinus:(Hex*)addr;
- (int)pushOperatorMinusAssign:(Hex*)addr andAddress:(Hex*)addr2;
- (int)pushOperatorOr:(Hex*)addr;
- (int)pushOperatorBitwiseOr:(Hex*)addr;
- (int)pushOperatorAnd:(Hex*)addr;
- (int)pushOperatorBitwiseAnd:(Hex*)addr;
- (int)pushWhile:(Hex*)addr;
- (int)pushLoopDefaultRegister;
- (int)pushLoopGoto;
- (int)pushLoadSymbol:(Hex*)hex;
- (int)pushLoadConstant:(Hex*)hex;
- (int)pushIf:(Hex*)addr;
- (int)pushIfConstant:(int)addr;
- (int)pushIfDefaultRegister;
- (int)pushElse:(Hex*)addr;
- (int)pushPreviousLabel;
- (int)pushNewLabel;

- (int)generateFreeAddress;
- (NSString*)generateFreeLabel;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import <Foundation/Foundation.h>
#import "GBAObject.h"

@interface ClassLocator : NSObject {
	
}

- (int) isa: (TypeName*)typename in: (GBAObject *)gbao;
- (int) locateType:(TypeName*)type;
- (int) isNativeType:(TypeName*)t;
- (int) isClassType:(TypeName*)t;
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "FNString.h"

@interface Compiler : NSObject {

	
	
}

- (void)compile:(FNString*)fileName;
- (void)scanFile:(FNString*)fileName;
- (int)scanFileRec:(FNString*)fileName;
- (int)compilable:(FNString*)fileName;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#include "HashTableStrings.h"
#include "Data.h"

@interface DataArray : NSObject {

	HashTableStrings *_datas;

}

- (DataArray *)ctor;
- (int) matchDataId:(int)tni returns:(void*)rString;
- (int) matchData:(Data *)data;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "../../liblisparm/RamDisk.h"//--FIXME
/*
 * The typename gets defined in memory (as a typename in a locator system)
 * and can be written to file
 * later on (ELF, misc obj files, ...)
 */

#define STRING(i) \
	"i" \

#define WRITEUBERDATAMAC(TYPENAME) \
	struct { int length; \
		void* TYPENAME; \
		}; \

#define WRITETYPEDATA \
	typedef struct DATAX { \
		int length; \
		void *data; \
		} DATAX; \

#define WRITEDATAMAC \
	DATAX datax; \

//--FIXME datastruct->typename
#define DATADEREF(typename) \
	->typename \

#define MATCHDATAANDTYPEID(datastruct, typename) \
	if (typename == datastructDATADEREF(typename)) \
		return 1; \
	else \
		return 0; \

typedef struct __Data_struct { int id; int datalength; void *data; } __Data_struct;

@interface Data : NSObject {
	__Data_struct *_data;
	int type;
}

- (void*)data;
- (int) setData:(void*)data;
- (int) type;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "GBAObject.h"

@interface Dispatcher : NSObject {

	NSMutableArray *_returns;
			
}

- (void) addNode:(GBAObject*)node;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import <Foundation/Foundation.h>
#import "Tuple.h"

enum { 
	UNKNOWNFILEFORMAT = -2, 
	NOENDOFINTERFACE = -3, 
	INTERFACESTARTBRACENOTFOUND = -4,
	INTERFACEWORDNOTFOUND = -5,
	INTERFACEINVALIDMETHODDEFINITION = -6,
	//INTERFACERETURNTYPEDOESNOTEXIST = -7,
	INTERFACERETURNTYPEISNOTNATIVE = -8,
	INTERFACEFUNCTIONNAMEILLEGALCHARACTER = -9,
	INTERFACEMETHODNOARGUMENTTYPE = -10,
	
};

@interface Error : NSObject {
	NSMutableArray *_errorstrs;
}

-(void)addError:(int)ei;
-(void)addErrorTuple:(Tuple*)t;
-(NSMutableArray*)getErrors;
-(int)errorset;
-(void)clear;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import <Foundation/Foundation.h>
#import "Error.h"

//file status & error ints 
enum { SUBCOMPILENOT = -2,
		SUBCOMPILENOMKSTEMP = -3,
		SUBCOMPILENOFDOPEN = -4,
		SUBCOMPILECANNOTFORK = -5,
		SUBCOMPILECANNOTLOCK = -6,
		SUBCOMPILECANNOTUNLOCK = -7,
		SUBCOMPILEINVALIDRETURNTYPE = -8,
		SUBCOMPILEINVALIDFUNCNAME = -9,
		SUBCOMPILEINVALIDARGS = -10,
		SUBCOMPILEINVALIDFUNCDEF = -11,

		OBJCHEADERCOMPILE = -100,
		OBJCSOURCECOMPILE = -101,
		PURECCOMPILE = -102,
};

@interface ErrorSubCompiler : Error {
}

-(void)addError:(int)ei;
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _GBA_FILEBUFFER_H_
#define _GBA_FILEBUFFER_H_

#import <Foundation/Foundation.h>


@interface FileBuffer : NSObject {
	NSString *_string;
}

- (FileBuffer*)ctor:(NSString*)s;
- (NSString*)stringFromIndex:(int)start toIndex:(int)end;
- (NSString*)string;
- (int)length;

@end

#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * filename String : file buffer agent
 */
#ifndef _OBJCARMFILENAME_H_
#define _OBJCARMFILENAME_H_

#import <Foundation/Foundation.h>
//#import <AppKit/AppKit.h>
#import "FileBuffer.h"
#import "ScanSystem.h"
#import "Error.h"
#import "Status.h"
#include <sys/file.h>

@interface OBJCARMFileName : NSString {
	
	FileBuffer *_fileBuffer;
	Error *_errorobj;
	Status *_statusobj;
	//ScanSystem *scansys;
	
}

- (OBJCARMFileName*)ctor;

- (FileBuffer*)buffer;

- (int) scan;
- (int) scancompile;
- (int) readInFile;
- (int) isheader;//should be fuzzynated
- (int) issource;
- (int) isCHeader;
- (int) isCSource;
- (void) addStatus:(int)status;//FIXME obj instead of int
- (void) addError:(int)e;

- (NSString*)stringFromIndex:(int)start toIndex:(int)end;

@end

#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * filename String : file buffer agent
 */
#ifndef _FILENAMESTREAM_H_
#define _FILENAMESTREAM_H_

#import <Foundation/Foundation.h>
#include <sys/file.h>

@interface FileNameStream : NSObject {

	FILE *_fp;

}

- (FileNameStream*)ctor;
- (int)open:(NSString*)filename;
- (char) get;
- (char) get:(int)index;
- (int)close;

@end

#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * filename String : file buffer agent
 */
#ifndef _FNSTRING_H_
#define _FNSTRING_H_

#import <Foundation/Foundation.h>
//#import "../../liblisparm/FileBuffer.h"
#import "FileBuffer.h"
#import "ScanSystem.h"
#import "Error.h"
#import "Status.h"
#include <sys/file.h>

@interface FNString : NSObject {
	NSString *_filename;	
	FileBuffer *_filebuffer;
	Error *_errorobj;
	Status *_statusobj;
	//ScanSystem *scansys;
	
}

- (FNString*)ctor:(NSString*)filename;

- (FileBuffer*)buffer;
- (NSString*)bufferstring;

- (int) scan;
- (int) scancompile;
- (int) readInFile;
- (int) isheader;//should be fuzzynated
- (int) issource;
- (int) isCHeader;
- (int) isCSource;
- (void) addStatus:(int)status;//FIXME obj instead of int
- (void) addStatusFirst:(int)status andSecond:(NSObject*)oi;//FIXME obj instead of int

- (void)addStatus:(int)status String:(NSString**)s;
- (void)printStatus:(int)status;

- (void) addError:(int)e;
- (void) addErrors:(Error*)err;

- (NSString*)stringFromIndex:(int)start toIndex:(int)end;

- (Tuple*)getLastStatus;

@end

#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _FORM_H_
#define _FORM_H_

#import <Foundation/Foundation.h>
#import "Error.h"
#import "Status.h"
@class ByteCodeMachine;

@interface Form : NSObject {
	NSMutableString *_formstring;
	Error *_errorobj;
	Status *_statusobj;

	struct machine { ByteCodeMachine *machine ; } _machine;
	
}

- (Form*)initWithString:(NSString*)s;
- (NSString*)string;
- (void)setString:(NSString*)s;

- (int)skipWhiteSpace:(NSString*)buffer atIndex:(int)idx;
- (int)skipWhiteSpaceBackwards:(NSString*)buffer atIndex:(int)idx;
//- (int)compile:(ByteCodeMachine*)machine withIndex:(int)index;
- (int)formatLisp;

- (void) addStatus:(int)s;//FIXME obj instead of int
- (void) addError:(int)e;

- (void) reverse;

@end

#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>

//NOTE:
//each _vector coordinate is a process id for multithreaded compilation.

@interface Fuzzy : NSObject {

	int _matrix[4][4];
	int _vector[4];

}

- (int)mulinit:(int*)_rv;
- (int) mul:(int*)_v and:(int**)_m returns:(int*)_rv;
- (double)fitnessForMax:(int)max;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import <Foundation/Foundation.h>
#import "TypeNameArray.h"
#import "MethodNameArray.h"

@interface GBAObject : NSObject {

	NSString *name;

	//types and methods of object
	TypeNameArray *typenamearray;
	MethodNameArray *methodnamearray;
}

- (NSString *)string;
- (int)isaid:(int)typenamei;
- (int)hasaid:(int)methodnamei;

- (int)isa:(TypeName*)typename;
- (int)hasa:(MethodName*)methodname;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef _GBAO_HASHTABLE_H_
#define _GBAO_HASHTABLE_H_

#import <Foundation/Foundation.h>


@interface HashTable : NSObject {
	int **_table;
	int _size;
}

- (int)size;
//- (HashTable *)ctor:(int)sz;

@end
#endif
//
//  HashTableStrings.h
//  libobjcgbarm
//
//  Created by link on 25/10/12.
//  Copyright 2012 vub. All rights reserved.
//

#ifndef _GBAO_HASHTABLESTRINGS_H_
#define _GBAO_HASHTABLESTRINGS_H_

#import <Foundation/Foundation.h>
#import "HashTable.h"


@interface HashTableStrings : HashTable {

}

- (int)matchWithKey:(int)key returns:(NSString*)rString;
- (HashTableStrings *)ctor:(int)sz;

@end
#endif
//
//  HashTableTupleInts.h
//  libobjcgbarm
//
//  Created by link on 25/10/12.
//  Copyright 2012 vub. All rights reserved.
//

#ifndef _GBAO_HASHTABLESTRINGS_H_
#define _GBAO_HASHTABLESTRINGS_H_

#import <Foundation/Foundation.h>
#import "HashTable.h"


@interface HashTableTupleInts : HashTable {

}

- (int)matchWithKey:(int)key returns:(NSString*)rString;
- (HashTableTupleInts *)ctor:(int)sz;

@end
#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>

@interface Hex : NSObject {

	int _hex;//FIXME long

}

- (Hex*) ctorString:(NSString*)word;
- (Hex*) ctorInt:(int)word;
- (Hex*) ctor:(Hex*)h;
- (int) getNumber;
- (int) number;
- (NSString*) hexnumberstring;
- (Hex*) setNumber:(int)h;
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "ByteCodeMachine.h"

@interface JavaByteCodeMachine : ByteCodeMachine {

}

- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#include "HashTableStrings.h"
#include "MethodName.h"

@interface MethodNameArray : NSObject {
	
	HashTableStrings *_methodnames;
	
}

- (MethodNameArray *)ctor;
- (int) matchMethodNameId:(int) tni;
- (int) matchMethodName:(MethodName *)tn;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>

//FIXME base class for methodname & typename
@interface MethodName : NSObject {
	int methodid;
	NSString *name;
}

- (MethodName *)ctor:(int)i withMethodName:(NSString *)n;
- (NSString *)string;
- (int)type;

@end

/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import <Foundation/Foundation.h>
#import "GBAObject.h"
#import "TypeNameArray.h"
#import "DataArray.h"

@interface Object : GBAObject {

	TypeNameArray *_typenames;
	DataArray *_datas;
	
}

- (int) writeOn:(Disk*)disk data:(void *)data;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import <Foundation/Foundation.h>
#import "GBAObject.h"

@interface ObjectLocator : NSObject {
	
}

- (int) isa: (TypeName*)typename in: (GBAObject *)gbao;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __OPERATOR_H_
#define __OPERATOR_H_
#import <Foundation/Foundation.h>
#import "Hex.h"

// These are basic types, SymbolName is for runtime object typing

@interface Operator : NSObject {
	NSString*_name;
	Hex *_address;
}

- (Operator*) definwWithName:(NSString*)name andAddress:(Hex*)address;
- (Hex*)address;
- (NSString*)name;
- (NSString*)string;

@end

#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "Operator.h"
#import "Hex.h"

// These are basic types, TypeName is for runtime object typing

@interface OperatorTable : NSObject {
	NSMutableArray *_array;
}
- (OperatorTable*)ctor;
- (Operator*) getObjectWithIndex:(int)si;
- (Operator*) getObject:(Operator*)ti;
- (Operator*) getOperator:(NSString*)s;
- (Operator*) searchForHex:(Hex*)hex;
- (void) addObject:(Operator*)s;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>


@interface ParseString : NSObject {
	NSString *string;
}

- (ParseString*)ctor:(NSString*)s;
- (bool) isSkipCharacterAtIndex:(int)index;
- (int)skipSkips:(int)i;//return index after skipping \W
- (NSString*)getWordUntilCharacter:(unichar)c startingAt:(int)i;
- (bool) eqString:(NSString*)s;
- (int) isTypedWell;
- (NSString *)string;
- (NSString*)substringAtIndex:(int)i;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>

@interface ParseTree : NSObject {
	ParseTree *_left;
	ParseTree *_right;
}

- (ParseTree*)ctor;
- (void)setLeft:(ParseTree*)tl;
- (void)setRight:(ParseTree*)tr;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "ParseTree.h"

@interface ParseTreeOp : ParseTree {
	char _op;
}

- (void)setOp:(char) c;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "ParseTree.h"

@interface ParseTreeOpLeaf : NSObject {
	
	NSString *_operand;
 
}

- (ParseTreeOpLeaf*)ctor:(NSString*)opnd;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#include "FNString.h"

@interface Scanner : NSObject {

}

- (int)scanFile:(FNString*)filename;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>


@interface ScanSystem : NSObject {


	
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import <Foundation/Foundation.h>

@interface Stack : NSObject {

	NSMutableArray*_stack;

}

- (void)push:(NSObject*)o;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "TupleInt.h"
#import "Tuple.h"

enum { 
	NOMETHODSDECLAREDINCLASS = -1, 
	NONATIVERETURNTYPE = -2,
};

@interface Status : NSObject {

	NSMutableArray *_statusstrs;
	
}

- (void) addStatus:(int)si;
- (void) addStatusTuple:(TupleInt*)ti; 
- (void) addStatus:(int)si withObject:(NSObject*)oi;
- (Tuple*)getObject:(int)si;
- (int)size;
- (int)length;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import <Foundation/Foundation.h>
#import "Structure.h"

@interface StructureBracket : Structure {


}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import <Foundation/Foundation.h>

@interface Structure : NSObject {


}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __SYMBOLARM_H_
#define __SYMBOLARM_H_
#import <Foundation/Foundation.h>
#import "Symbol.h"

@interface SymbolArm : Symbol {
	NSString* _registernumber;
	int _bracedepth;
}

- (int) defineWithId:(int)typeid andName:(NSString*)name;
- (Symbol*)ctor:(int)i withSymbolName:(NSString *)n andValue:(NSString*)val andAddress:(int)addy andRegisterNumber:(int)rn;
- (int)getRegisterNumber;

@end

#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __SYMBOL_H_
#define __SYMBOL_H_
#import <Foundation/Foundation.h>
#import "Hex.h"
#import "Form.h"

// These are basic types, SymbolName is for runtime object typing

typedef int TYPEID;
typedef long int TYPE;

//NOTE : do not make a type 0
/*static const TYPE ctype = 1;//character type
static const TYPE itype = 2;//integer type
static const TYPE vtype = 4;//vector type
static const TYPE stype = 8;//string type
static const TYPE ftype = 16;//float type
static const TYPE symtype = 32;//string type
static const TYPE formtype = 64;//string type
static const TYPE ltype = 128;//string type
*/

enum {
	ctype = 1,
	itype = 2,
	vtype = 4,
	stype = 8,
	ftype = 16,
	symtype = 32,
	formtype = 64,
	ltype = 128,
	functype = 256,
};

@interface Symbol : NSObject {
		//type of symbol
		TYPE _id;
		//ascii name of symbol
		NSString *_name;
		//value of symbol, can be a Lisp form
		Form* _value;
		//address
		Hex*_address;
		//documentation string
		struct documentation { NSString *string; } *_documentation;
}

- (Symbol*)ctor:(int)i withSymbolName:(NSString *)n;
- (Symbol*)ctor:(int)i withSymbolName:(NSString *)n form:(NSString*)form;
- (Symbol*)ctor:(int)i withSymbolName:(NSString *)n andAddress:(Hex*)addy;
- (Symbol*)ctor:(int)i withSymbolName:(NSString *)n andValue:(NSString*)val andAddress:(Hex*)addy;
- (Symbol*)ctorName:(NSString*)symname form:(Form*)form;

- (NSString *)string;
- (NSString *)name;
- (NSString *)value;
- (Hex*)address;
- (TYPE)type;

- (void)initDocString;
@end

#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "SymbolArm.h"
#import "SymbolTable.h"
#import "Hex.h"

// These are basic types, TypeName is for runtime object typing

@interface SymbolTableArm : SymbolTable {
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "Symbol.h"
#import "Hex.h"

// These are basic types, TypeName is for runtime object typing

@interface SymbolTable : NSObject {
	NSMutableArray *_array;
}

- (SymbolTable*)ctor;
- (Symbol*) getObjectWithIndex:(int)si;
- (Symbol*) getObject:(Symbol*)ti;
- (Symbol*) getString:(NSString*)s;
- (Symbol*) searchForHex:(Hex*)hex;

- (void) addObject:(Symbol*)s;
- (int) addObjectExists:(Hex*)h form:(Form*)f;
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import <Foundation/Foundation.h>

@interface Tuple : NSObject {

	NSObject *first;
	NSObject *second;

}

//ctor
- (Tuple*)addFirst:(NSObject*)fst andSecond:(NSObject*)snd;
- (NSObject*)first;
- (NSObject*)second;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import <Foundation/Foundation.h>

@interface TupleInt : NSObject {

	int first;
	NSObject *second;

}

//ctor
- (TupleInt*)addFirst:(int)fst andSecond:(NSObject*)snd;
- (TupleInt*)addFirstInt:(int)fst andSecond:(NSObject*)snd;
- (int)first;
- (NSObject*)second;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import <Foundation/Foundation.h>
#import "Tuple.h"

@interface TupleIterator : NSObject {

	Tuple* _current;
}

- (TupleIterator*)ctor:(Tuple*)t;
- (Tuple*)next;
- (int)atEnd;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "Type.h"

// These are basic types, TypeName is for runtime object typing

@interface TypeChar : Type {

}

- (TypeChar*)ctor;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>

// These are basic types, TypeName is for runtime object typing

@interface Type : NSObject {

		int _id;
		NSString *_name;
}

- (int) defineWithId:(long int)typeid andName:(NSString*)name;
- (Type*)ctor:(long)i withTypeName:(NSString *)n;
- (NSString *)string;
- (int)type;
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "Type.h"

// These are basic types, TypeName is for runtime object typing

@interface TypeInt : Type {

}

- (TypeInt*)ctor;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#include "HashTableStrings.h"
#include "TypeName.h"

@interface TypeNameArray : NSObject {

	HashTableStrings *_typenames;

}

- (TypeNameArray *)ctor;
- (int) matchTypeNameId:(int)tni returns:(NSString*)rString;
- (int) matchTypeName:(TypeName *)tn;
- (int)size;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "../../liblisparm/Disk.h"////

#import "Data.h"

/*
 * The typename gets defined in memory (as a typename in a locator system)
 * and can be written to file
 * later on (ELF, misc obj files, ...)
 */

WRITETYPEDATA

#define WRITETYPE(NAME) \
	typedef struct TName { \
			int id; \
			char *NAME; \
			WRITEDATAMAC \
			} TName; \

// These are *not* basic types, TypeName is for runtime object typing in the object itself
@interface TypeName : NSObject {

		int _id;
		char *_name;
}

- (int) defineWithId:(long int)typeid andName:(NSString*)name;
- (TypeName *)ctor:(long)i withTypeName:(NSString *)n;
- (NSString *)string;
- (long int)type;

- (int) subCompileSelfOn:(Disk*)disk;
- (int) subCompileSelfOn:(Disk*)disk withFormat:(int)fmt;
- (int) this:(TypeName*) tn isa:(const char *)str;

- (int)writeOn:(Disk*)disk data:(Data*)data;
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "../../liblisparm/Disk.h"

#import "Data.h"

/*
 * The typename gets defined in memory (as a typename in a locator system)
 * and can be written to file
 * later on (ELF, misc obj files, ...)
 */

WRITETYPEDATA

#define WRITETYPEMEM(NAME) \
	typedef struct TName { \
			int id; \
			char *NAME; \
			WRITEDATAMAC \
			} TName; \

@interface TypeNameMem : NSObject {

		int _size;
		char *_data;

}

- (int) defineWithId:(int)typeid andName:(NSString*)name;
- (TypeNameMem *)ctor:(int)i withTypeName:(NSString *)n;
- (NSString *)string;
- (int)type;

- (int) subCompileSelfOn:(Disk*)disk;
- (int) subCompileSelfOn:(Disk*)disk withFormat:(int)fmt;
- (int) this:(TypeNameMem*) tn isa:(const char *)str;

- (int)writeOn:(Disk*)disk data:(Data*)data;
- (NSString*)reverse:(NSString*)str;
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "Type.h"
#import "Hex.h"

// These are basic types, TypeName is for runtime object typing

@interface TypeTable : NSObject {
	NSMutableArray *_array;
}

- (TypeTable*)ctor;
- (Type*) getObjectWithIndex:(int)si;
- (Type*) getObject:(Type*)ti;
- (Type*) searchForHex:(Hex*)hex;
- (int) hasType:(NSString*)t;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "Type.h"

// These are basic types, TypeName is for runtime object typing

@interface TypeVoid : Type {
}

- (TypeVoid*)ctor;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>

@interface WordBase : NSObject {
	NSString *_word;
}

- (WordBase*)ctor:(NSString *)n;
- (NSString *)string;

- (int)isWord:(NSString*)w;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import <Foundation/Foundation.h>
#import "WordBase.h"
#import "TupleInt.h"

@interface Word : WordBase {
}

- (int)isElseClause;
- (int)isWhile;
- (int)isWhileClause;
- (int)isIf;
- (int)isIfClause;
- (int)isElse;
- (int)isOpeningBrace;
- (int)isClosingBrace;

- (TupleInt*)skipWhiteSpace:(NSString*)word withIndex:(int)idx;

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "6502AssemblerMachine.h"

@implementation NesAssemblerMachine

- (NesAssemblerMachine*)ctor
{
	_type = HAVE_MACHINE_6502ASM;
	_freeaddycounter = 0;

	NSLOG(@"*** arm-lisp running for 6502 target");
	NSLOG(@"*** Non-Heap, 6502 assembly target - Hex number system loaded");

	return self;
}

- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2
{
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"sta ", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ $%@", @"lda ", [hex2 hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"6502 : pushed definition with lda $%@ and sta #%@",[hex hexnumberstring],[hex2 hexnumberstring]);
	return 0;
}

- (int)pushAssignment:(Hex*)hex with:(Hex*)hex2
{
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"sta ", [hex2 hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	return 0;
}

- (int)pushOperatorPlus:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"adc ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorPlusConstant:(Hex*)hex
{
	//lda reg
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"adc ", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG(@"6502 : pushed Plus Constant");
	return 0;
}

- (int)pushOperatorPlusSymbol:(Hex*)hex
{
	//lda reg
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"adc ", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG(@"6502 : pushed Plus Symbol");
	return 0;
}

- (int)pushOperatorMulConstant:(Hex*)hex
{
	//lda reg
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"FIXME mul ", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG(@"6502 : pushed Mul Constant");
	return 0;
}

- (int)pushOperatorMulSymbol:(Hex*)hex
{
	//lda reg
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"FIXME mul ", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG(@"6502 : pushed Mul Symbol");
	return 0;
}

- (int)pushOperatorMinus:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"sbc ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorPlusPlus:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"inc ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorMinusMinus:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"dec ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorPlusAssign:(Hex*)addr andAddress:(Hex*)addr2
{
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"lda ", [addr hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"adc ", [addr2 hexnumberstring]];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorMinusAssign:(Hex*)addr andAddress:(Hex*)addr2
{
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"lda ", [addr hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"sbc ", [addr2 hexnumberstring]];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushOperatorOr:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"ora ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushOperatorBitwiseOr:(Hex*)addr
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"ora ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushOperatorBitwiseExclusiveOr:(Hex*)addr
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"eor ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushOperatorBitwiseAnd:(Hex*)addr
{
	//lda reg
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"and ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushOperatorBitwiseOrAssign:(Hex*)addr andAddress:(Hex*)addr2
{

	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"lda ", [addr hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"ora ", [addr2 hexnumberstring]];//FIXME ORA ?
	[_bytecode addObject: s2];
	[_bytecode addObject: s];

}

- (int)pushOperatorBitwiseExclusiveOrAssign:(int)addr andAddress:(int)addr2
{

	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"lda ", [addr hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"eor ", [addr2 hexnumberstring]];//FIXME ORA ?
	[_bytecode addObject: s2];
	[_bytecode addObject: s];

}

- (int)pushOperatorAnd:(int)addr
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"and ", [addr hexnumberstring]];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushOperatorBitwiseAndAssign:(int)addr andAddress:(int)addr2
{

	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"lda ", [addr hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"and ", [addr2 hexnumberstring]];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushIf:(Hex*)hex
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateLabel]];
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"cmp ", [hex hexnumberstring]];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushLoadSymbol:(Hex*)hex
{
	NSString *s = [NSString stringWithFormat:@"%@ $%@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	NSLOG2(@"6502 assembler : pushed load symbol with lda $%@",[hex hexnumberstring]);
	return 0;
}

- (int)pushLoadConstant:(Hex*)hex
{
	NSString *s = [NSString stringWithFormat:@"%@ #%@", @"lda ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	NSLOG2(@"6502 assembler : pushed load symbol with lda #%@",[hex hexnumberstring]);
	return 0;
}
- (int)pushIfConstant:(int)i
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateLabel]];
	NSString *s2 = [NSString stringWithFormat:@"%@ %d", @"cmp ", i];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;

}

- (int)pushLoopDefaultRegister
{
	//TODO
	return 0;
}
- (int)pushLoopGoto
{
	//TODO
	return 0;
}
- (int)pushIfDefaultRegister
{
	//TODO
/*	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateLabel]];
	NSString *s2 = [NSString stringWithFormat:@"%@ %@", @"cmp ",];
	NSString *s3 = [NSString stringWithFormat:@"%@ %@", @"lda ",];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	return 0;
*/
	return 0;
}

- (int)pushElse:(Hex*)hex
{

	NSString *s2 = [NSString stringWithFormat:@"bcc label%@:", _freelabelcounter];//if before jump over else clause, FIXME bcc ?
	NSString *s = [NSString stringWithFormat:@"label%@:", [self generateLabel]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	return 0;

}

- (int)pushWhile:(Hex*)hex
{

	NSString *s2 = [NSString stringWithFormat:@"bcc label%@", _freelabelcounter];//branch after while block code, FIXME bcc ?
	NSString *s = [NSString stringWithFormat:@"label%@:", [self generateLabel]];//loop; label
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	return 0;

}

- (int)pushPreviousLabel
{

	NSString *s = [NSString stringWithFormat:@"label%@:",_freelabelcounter];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushNewLabel
{

	NSString *s = [NSString stringWithFormat:@"label%@:",[self generateFreeLabel]];
	[_bytecode addObject: s];
	return 0;
}

- (int)pushBranch:(Hex*)hex
{

	NSString *s = [NSString stringWithFormat:@"bcc %@",_freelabelcounter];
	[_bytecode addObject: s];
	return 0;
}


- (NSString*)getLastLabel 
{
	//TODO 
	return 0;
}
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ArmAssemblerMachine.h"

@implementation ArmAssemblerMachine

- (ArmAssemblerMachine*)ctor
{
	_type = HAVE_MACHINE_ARMASM;
	_freeaddycounter = 0;
	return self;
}

- (int)pushLoadSymbol:(Hex*)hex
{
	NSString *s = [NSString stringWithFormat:@"%@, #0x%@", @"ldr r0", [hex hexnumberstring]];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed load symbol with ldr r0, #0x%@",[hex hexnumberstring]);
	return 0;
}

- (int)pushLoadConstant:(Hex*)hex
{
	NSString *s = [NSString stringWithFormat:@"%@, =%@", @"ldr r0", [hex hexnumberstring]];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed load constant with ldr r0, =%@",[hex hexnumberstring]);
	return 0;
}

- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2
{
	NSString *s2 = [NSString stringWithFormat:@"%@, 0x%@", @"str r1", [hex hexnumberstring]];
	NSString *s = [NSString stringWithFormat:@"%@, =%@", @"ldr r1", [hex2 hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed definition with ldr r1, =%@ ; str r1,#0x%@ ; ",[hex2 hexnumberstring],[hex hexnumberstring]);
	return 0;
}

- (int)pushOperatorPlus:(Hex*)hex
{
	NSString *s = [NSString stringWithFormat:@"%@ %@", @"add ", [hex hexnumberstring]];
	[_bytecode addObject: s];
	NSLOG3(@"arm assembler : pushed plus r1,=%@ and str r0,=%@",[hex hexnumberstring],[hex hexnumberstring]);
	return 0;
}

- (int)pushOperatorPlusConstant:(NSString*)val
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"add "];
	NSString *s = [NSString stringWithFormat:@"%@, =%@", @"ldr r1", val];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed plus constant ldr r1,=%@ and add r0,r0,r1", val);
	return 0;
}

- (int)pushOperatorPlusSymbol:(Hex*)hex
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"add "];
	NSString *s = [NSString stringWithFormat:@"%@, #0x%@", @"ldr r1", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed plus symbol ldr r1,#0x%@ and add r0,r0,r1", [hex hexnumberstring]);
	return 0;
}

- (int)pushOperatorMinusConstant:(NSString*)val
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"sub "];
	NSString *s = [NSString stringWithFormat:@"%@, =%@", @"ldr r1", val];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed minus constant ldr r1,=%@ and sub r0,r0,r1", val);
	return 0;
}

- (int)pushOperatorMinusSymbol:(Hex*)hex
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"sub "];
	NSString *s = [NSString stringWithFormat:@"%@, #0x%@", @"ldr r1", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed minus symbol ldr r1,#0x%@ and sub r0,r0,r1", [hex hexnumberstring]);
	return 0;
}

- (int)pushOperatorMulConstant:(NSString*)val
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"mul "];
	NSString *s = [NSString stringWithFormat:@"%@, =%@", @"ldr r1", val];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed multiply constant ldr r1,=%@ and mul r0,r0,r1", val);
	return 0;
}

- (int)pushOperatorMulSymbol:(Hex*)hex
{
	NSString *s2 = [NSString stringWithFormat:@"%@ r0,r0,r1", @"mul "];
	NSString *s = [NSString stringWithFormat:@"%@, #0x%@", @"ldr r1", [hex hexnumberstring]];
	[_bytecode addObject: s];
	[_bytecode addObject: s2];
	NSLOG3(@"arm assembler : pushed multiply symbol ldr r1,#0x%@ and mul r0,r0,r1", [hex hexnumberstring]);
	return 0;
}

- (int)pushIf:(Hex*)hex
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateFreeLabel]];
	//NOTE major results are in r0 register (throughout this ArmAssemblerMachine.m file)
	NSString *s2 = [NSString stringWithFormat:@"%@", @"cmp r0,r1"];
	NSString *s3 = [NSString stringWithFormat:@"%@ #0x%@", @"ldr r1,", [hex hexnumberstring]];
	[_bytecode addObject: s3];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed if ldr r1,#0x%@ ; cmp r0,r1 ; bne labelX", [hex hexnumberstring]);
	return 0;
}

- (int)pushIfConstant:(int)i
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateFreeLabel]];
	//NOTE major results are in r0 register (throughout this ArmAssemblerMachine.m file)
	NSString *s2 = [NSString stringWithFormat:@"%@", @"cmp r0,r1"];
	NSString *s3 = [NSString stringWithFormat:@"%@ =%d", @"ldr r1,", i];
	[_bytecode addObject: s3];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	NSLOG3(@"arm assembler : pushed if constant ldr r1,=%d ; cmp r0,r1 ; bne label%d", i, _freelabelcounter);
	return 0;
}

- (int)pushIfDefaultRegister
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateFreeLabel]];
	//NOTE major results are in r0 register (throughout this ArmAssemblerMachine.m file)
	NSString *s2 = [NSString stringWithFormat:@"%@", @"cmp r0,r1"];
	NSString *s3 = [NSString stringWithFormat:@"%@", @"ldr r1,r0"];
	[_bytecode addObject: s3];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed if ldr r1,r0 ; cmp r0,r1 ; bne label%d",_freelabelcounter);
	return 0;
}

- (int)pushLoopDefaultRegister
{

	NSString *s = [NSString stringWithFormat:@"%@ %@", @"bne ", [self generateFreeLabel]];
	//NOTE major results are in r0 register (throughout this ArmAssemblerMachine.m file)
	NSString *s2 = [NSString stringWithFormat:@"%@", @"cmp r0,r1"];
	NSString *s3 = [NSString stringWithFormat:@"%@", @"ldr r1,r0"];
	[_bytecode addObject: s3];
	[_bytecode addObject: s2];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed loop condition ldr r1,r0 ; cmp r0,r1 ; bne label%d",_freelabelcounter);
	return 0;

}
- (int)pushLoopGoto:(NSString*)l
{

	NSString *s = [NSString stringWithFormat:@"goto %@", l];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed goto %@",l);
	return 0;

}

- (int)pushPreviousLabel
{

	NSString *s = [NSString stringWithFormat:@"label%d:",_freelabelcounter];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed previous label%d:",_freelabelcounter);
	return 0;
}

- (int)pushNewLabel
{

	NSString *s = [NSString stringWithFormat:@"label%@:",[self generateFreeLabel]];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed new label%d:",_freelabelcounter);
	return 0;
}
- (int)pushNewLabel:(NSString*)l
{

	NSString *s = [NSString stringWithFormat:@"%@:",l];
	[_bytecode addObject: s];
	NSLOG2(@"arm assembler : pushed new label : %@",l);
	return 0;
}

- (NSString*)getLastLabel 
{
	NSString *s = [NSString stringWithFormat:@"label%d:",_freelabelcounter];
	return s;
} 

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "ArmCompilerBase.h"


@implementation ArmCompilerBase

/*
 * Arm Compiler ObjC pattern matcher
 */

- (int) scanObjCMethodDeclarationIn:(FileName*)fileName withIndex:(int*)i {
	NSString*funcName;
	NSMutableArray*Args;
	struct RType* returnType;
	
	int oldidx = *i;
	
	while(++(*i) < [[fileName buffer] length]) {
		if ([[fileName buffer] characterAtIndex:(*i)] == '(') {
			returnType = NULL;
			
			
			if ([self scanDeclarationForType:[fileName buffer] withIndex:i returns:returnType] < 0) {
				*i = oldidx; 
				continue;
				////return SUBCOMPILEINVALIDRETURNTYPE;
			}
			if ([self scanDeclarationForFuncName:[fileName buffer] withIndex:i returns:funcName] < 0) {
				*i = oldidx;
				continue;
				////return SUBCOMPILEINVALIDFUNCNAME;
			}
			if ([self scanDeclarationForArgs:[fileName buffer] withIndex:i returns:Args] < 0) {
				*i = oldidx; 
				continue;
				////return SUBCOMPILEINVALIDARGS;
			}
			
			if (oldidx == *i)
				return SUBCOMPILEINVALIDFUNCDEF;
		}
	}
	
	return 0;
	
}

- (int) writeDeclarationWithReturnTypeToHeader:(struct RType*)returnType withFuncName:(NSString*)funcName andArgs:(NSMutableArray*)Args onfno:(int)fno {

	write(fno, (char *)returnType->rtypestring, strlen((char *)returnType->rtypestring));
	write(fno, " ", 1);
	write(fno, (char *)funcName, strlen((char *)funcName));
	write(fno, "(", 1);
	int j = -1;
	while (++j < [Args count]-1) {
		write(fno, (char *)[Args objectAtIndex:j], strlen((char *)[Args objectAtIndex:j]));
		write(fno, (char *)", ",2);
	}
	write(fno, (char *)[Args objectAtIndex:j], strlen((char *)[Args objectAtIndex:j]));
	write(fno, ")", 1);//FIXME ") {"
	
	return 0;

}

- (int) scanDeclarationForType:(NSString*)pstr withIndex:(int*)i returns:(struct RType*)rType{
	
	NSString*is;
	int subcount;
	while ([pstr characterAtIndex:*i] != ')' || subcount > 0) {
		
		if ([pstr characterAtIndex:*i] == '(') //scan for nested (((())) types e.g. function pointers
			subcount++;
		else if ([pstr characterAtIndex:*i] == ')') 
			subcount--;

		
		if (*i > [pstr length]) {
			rType = (struct RType*)malloc(sizeof(struct RType));
			rType->rtypestring = @"";
			rType->id = -1;
			return -1;
		}
		is += [pstr characterAtIndex:*i];
	}
	
	long r = random();
	long r2 = random();
	long r3 = r2;
	long result = 0;
	
	if ([_classLocator locateType:[[TypeName init] ctor:r withTypeName:is]] < 0) {
		rType = (struct RType*)malloc(sizeof(struct RType));
		rType->rtypestring = @"";
		
		//make number string for id
		for ( ;; ) {
			
			r3 = r2 % 2;
			r2 -= (r2 % 10);//base 10
			
			result += r3;
			
		}
		
		rType->id = result;
		//rType->id = r2 % INT_MAX;//--FIXME repeated ids
		return -1;
	}
		
	//skip whitespace
	for ( ;[pstr characterAtIndex:*i] == ' '
		   || 
		   [pstr characterAtIndex:*i] == '\t'
		   || 
		 [pstr characterAtIndex:*i] == '\n'; )
		(*i)++;
	
	rType = (struct RType*)malloc(sizeof(struct RType));
	rType->rtypestring = is;
	rType->id = r2 % INT_MAX;//--FIXME repeated ids
	
	return 0;
	
}

		  
- (int) scanDeclarationForFuncName:(NSString*)pstr withIndex:(int*)i returns:(NSString*)rName{
	NSString*is;
	while ([pstr characterAtIndex:*i] != '(') {
				  
		if (*i > [pstr length]) {
			rName = @"";
			return -1;
		}
		is += [pstr characterAtIndex:*i];
	}
			  
			  
	rName = is;
	return 0;	  
}
		  

- (int) scanDeclarationForArgs:(NSString*)pstr withIndex:(int*)i returns:(NSMutableArray*)rArgs{
	
	NSMutableArray*lis;
	struct RType*is;
	while ([pstr characterAtIndex:*i] != '{') {
		
		while ([pstr characterAtIndex:*i] != '(') 
			;
		
		if (*i > [pstr length]) {
			rArgs = lis;
			return 0;
		}
		if ([self scanDeclarationForType:pstr withIndex:i returns:is] < 0) {
			rArgs = lis;
			return -1;
		}
		else {
			//scan for argname
			NSString*argname;
			while ((*i) < [pstr length]) {
				if ([pstr characterAtIndex:*i] != ' ' || [pstr characterAtIndex:*i] != ')') {
					argname += [pstr characterAtIndex:*i];
				} else {
					is->rtypestring = [NSString stringWithFormat:@"%@/%@",is,argname];
					break;
				}
				(*i)++;
			}
		}	
		
		is += [pstr characterAtIndex:*i];
		
		//skip whitespace
		while ([pstr characterAtIndex:*i] == ' ' 
			   || 
			   [pstr characterAtIndex:*i] == '\t' 
			   || 
			   [pstr characterAtIndex:*i] == '\n')
			(*i)++;
		
		//FIXME rtypestring
		if ([_classLocator locateType:[[TypeName init] ctor:-1 withTypeName:is->rtypestring]] < 0) {
			[lis addObject:is->rtypestring];//--FIXME rtypestring
		}
	}
	
	return 0;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "ArmCompiler.h"


@implementation ArmCompiler

- (void)compile:(FNString*)fileName {
	
	_armScanner = [ ArmScanner new ];
	[ _armScanner scanFile:fileName withCompiler: self ];
	
	return;
}

- (void) scanFile:(FNString*)fileName {

	[self scanFileRec:fileName];
	
}

- (int)scanFileRec:(FNString*)fileName {
	int e = -1;
	//ask if buffer has right block scopes syntax
	if ((e = [self compilable:fileName]) < 0)
		[fileName addError:e];
	
	return 0;
}

- (int)compilable:(FNString*)fileName {

	if ([fileName isheader]) {
		return [self compilableheader:fileName];
	} else if ([fileName issource]) {
		return [self compilablesource:fileName];
	} else {
		return UNKNOWNFILEFORMAT;//error
	}
	
	return 0;
	
}

- (int)compilableheader:(FNString*)fileName {
	
	FileBuffer *buffer = [fileName buffer];//reverse buffer
	NSString *bufferstring = [buffer string];//reverse buffer
	NSString *str = @"";
	int i = -1;
	int ti = 0;
	
	while (++i < [buffer length]) {
		
		if ([buffer characterAtIndex:i] != ' ' 
			 ||
			 [buffer characterAtIndex:i] != '\t'
			 ||
			[buffer characterAtIndex:i] != '\n') {
			
			int j = -1;	
			while (++j < 4) {
				str += [bufferstring characterAtIndex:j];
			}
		
			//FIXME scan for common C functions after '@end'
			
			if (str != @"dne@")//\n@end
				return NOENDOFINTERFACE;
		
			i += j;
		}
	}
	
	ti = i;
	
	//i--;//NOTE
	int newlineIndex = i;
	int braceIndex = i;
	int braceIndex2 = i;
	int nsbrace = 0;//number of skips before brace
	int semicolonIndex = i;
	newlineIndex = [self searchFor:buffer char:'\n' startingAt:i];
	braceIndex = [self searchFor:buffer char:'}' startingAt:i numberOfSkips:&nsbrace];
	braceIndex2 = [self searchFor:buffer char:'{' startingAt:i];
	semicolonIndex = [self searchFor:buffer char:';' startingAt:i];
	//i++;//skip newline
	
	switch (newlineIndex-i){
		case 0:{
			switch (braceIndex-i-nsbrace){
				case 1:{
					[fileName addStatus:NOMETHODSDECLAREDINCLASS];
					switch (braceIndex2 > braceIndex) {
						case 0:{
							[fileName addError:INTERFACESTARTBRACENOTFOUND];
							break;
						}
						case 1:{
							if ((i = [self searchFor:buffer string:@"ecafretni@" startingAt:braceIndex2]) == NOTFOUND) {
								[fileName addError:INTERFACEWORDNOTFOUND];
							}
							
							break;
						}
						default:{
							break;
						}
					}
					break;
				}
				default:{
					//switch (
					break;
				}
			}	
			break;
		}
		default:{
			break;
		}
	}
	
	//search start from right brace index (interface definition)
	i = ti-1;
	while (++i < braceIndex) {
		int methodsemicolonindex = [self searchFor:buffer char:';' startingAt:i];
		int methoddashindex = [self searchFor:buffer char:'-' startingAt:i];
		
		if (methodsemicolonindex && methoddashindex == NOTFOUND) {
			[fileName addError:INTERFACEINVALIDMETHODDEFINITION];
		}
		else if (methodsemicolonindex < methoddashindex) {
			
			NSString *methodstr = [buffer stringFromIndex:methodsemicolonindex toIndex:methoddashindex];
			
			//NOTE: errorcodes can be managed with pure C agent code (as not every system supports objC or C++
			int *errororstatuscodes = [self compilableInterfaceMethod:[self reverse:methodstr]];//NOTE be string
			while (errororstatuscodes != (int*)0 && sizeof(errororstatuscodes) > 0) {
			
				switch (*errororstatuscodes++) {
				case INTERFACERETURNTYPEISNOTNATIVE:{
					[fileName addStatus:NONATIVERETURNTYPE];//NOTE status, needs object locator in next pass
					break;
				}
				default:{
					break;
				}
				}
			}
			i = methoddashindex;
			continue;
		} 
		
	}
	
	return 0;
}

- (int)compilablesource:(FNString*)fileName {
	
	//subclass responsability	
	return 0;
}

- (int) searchFor:(NSString*)buffer char:(unichar)c startingAt:(int)startidx {
		int i = -1+startidx;
		while (++i < [buffer length]) {
			if ([buffer characterAtIndex:i] == c)
				return i;
		}
		
		return NOTFOUND;
}
	
- (int) searchFor:(NSString*)buffer char:(unichar)c startingAt:(int)startidx numberOfSkips:(int*)skips {
	int i = -1+startidx;
	while (++i < [buffer length]) {
		if ([buffer characterAtIndex:i] == c)
			return i;
		if ([buffer characterAtIndex:i] == '\n'//FIXME put in method
			||
			[buffer characterAtIndex:i] == '\t'
			||
			[buffer characterAtIndex:i] == ' ')
			*skips++;
	}

	return NOTFOUND;
}

- (int) searchFor:(NSString*)buffer string:(NSString*)s startingAt:(int)startidx {
	int i = -1+startidx;
	NSString *str = @"";
	
	while (++i < [buffer length]) {
	
		if ([buffer characterAtIndex:i] == ' '//FIXME put in method
			||
			[buffer characterAtIndex:i] == '\t'
			||
			[buffer characterAtIndex:i] == '\n') {
				str = @"";
				continue;
		}
		
		str += [buffer characterAtIndex:i];
		
		if (str == s)
			return i;
		
	}
	
	return NOTFOUND;
}

- (NSString*)reverse:(NSString*)str {
	NSString *reversestr = @"";
	
	int l = [str length];
	int i = 0;
	while (i++ < l){
		reversestr += [str characterAtIndex:i];
	}
	
	return reversestr;
}				 
			 
- (int*) compilableInterfaceMethod:(NSString*)methodstr {

	NSString* tmethodstr = methodstr;
	int *erroris = [self compilableCheckReturnType: tmethodstr];
	int *errorisstart = erroris;
	
	int *erroris2 = (int*)[self compilableCheckFunctionName: tmethodstr];
	memcpy((void*)erroris,(void*)(erroris2-errorisstart),sizeof(erroris2)-sizeof(erroris));

	//repeat for multiple argument methods
	while ([tmethodstr length] > 0) {
		
		
		int * erroris3 = (int*)[self compilableCheckFunctionArgs: tmethodstr];
		memcpy((void*)erroris,(void*)(erroris3-erroris2),sizeof(erroris3)-sizeof(erroris2));
	
		if ([tmethodstr length] > 0) {
			int *erroris4 = (int*)[self compilableCheckFunctionName: tmethodstr];
			memcpy((void*)erroris,(void*)(erroris4-erroris3),sizeof(erroris4)-sizeof(erroris3));
		}
	}
		
	return errorisstart;
	
}

- (int*)compilableCheckReturnType:(NSString*)methodstr {
	int *erroris = (int*)malloc(1024*sizeof(int));//FIXME C progr disease
	ParseString *tpmethodstr = [[ParseString new] ctor:methodstr];
	ParseString *tpstr = [[ParseString new] ctor:@""];
	int i = -1;
	while (++i < [methodstr length]) {
		if ([tpmethodstr isSkipCharacterAtIndex:i]) {
			continue;
		} else {
			tpstr += [methodstr characterAtIndex:i];
			int skipi;
			if ((skipi = [[[ParseString new] ctor:[tpstr string]] isTypedWell]) > 0) {
				methodstr = [tpmethodstr substringAtIndex:skipi];
				free(erroris);
				erroris = (int*)0;
				return erroris;
				
			}
		}
	
	}
								
	methodstr = @"";
	erroris[0] = INTERFACERETURNTYPEISNOTNATIVE;//NOTE status
	erroris++;
	return erroris;//return errors
			
}
	
- (int*)compilableCheckFunctionName:(NSString*)methodstrpart {
	int *erroris = (int*)malloc(1024*sizeof(int));
	int i = -1;
	ParseString*tpmethodstrpart = [[ParseString new] ctor:methodstrpart];
	
	while (++i < [methodstrpart length]) {
		if ([methodstrpart characterAtIndex:i] == '?'
			||
			[methodstrpart characterAtIndex:i] == '/'
			||
			[methodstrpart characterAtIndex:i] == '\\'
			||
			[methodstrpart characterAtIndex:i] == '\n'
			||
			[methodstrpart characterAtIndex:i] == ',') {
			methodstrpart = @"";
			erroris[0] = INTERFACEFUNCTIONNAMEILLEGALCHARACTER;
			methodstrpart = [tpmethodstrpart substringAtIndex:[methodstrpart length]];//FIXME length index
			return erroris;//return error
		} else if ([methodstrpart characterAtIndex:i] == ';') {
			free(erroris);
			erroris = (int)0;
			methodstrpart = [tpmethodstrpart substringAtIndex:i];
			return erroris;//set status to no args?
		} else if ([methodstrpart characterAtIndex:i] == ':') {
			free(erroris);
			erroris = (int)0;
			methodstrpart = [tpmethodstrpart substringAtIndex:i];
			return erroris;//set status to has args?
		}
		
	}
	
	return erroris;
	
}

- (int*)compilableCheckFunctionArgName:(NSString*)methodstrpart {
	return [self compilableCheckFunctionName:methodstrpart];
}

- (int*)compilableCheckFunctionArgs:(NSString*)methodstrpart {
	int *erroris = (int*)malloc(1024*sizeof(int));
	int i = 0;
	
	ParseString* ptstr = [[ParseString new] ctor:methodstrpart];
	i = [ptstr skipSkips:i];
	
	while (i < [methodstrpart length]) {
		if ([methodstrpart characterAtIndex:i++] == '(') {
			break;
		}
	}
	if (i >= [methodstrpart length]) {
		erroris[0] = INTERFACEMETHODNOARGUMENTTYPE;
		return erroris;
	}
	
	i = [ptstr skipSkips:i];
	while (i < [methodstrpart length]) {
		if ([methodstrpart characterAtIndex:i++] == ')') {
			break;
		}
	}
	
	erroris = [self compilableCheckFunctionArgName:[ptstr substringAtIndex:i]];//checks for valid argument characters
	return erroris;
	
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "ArmLispCompiler.h"
#import "Hex.h"
#import "ParseTreeOp.h"
#import "6502AssemblerMachine.h"
#import "ArmAssemblerMachine.h"
#import "Word.h"

@implementation ArmLispCompiler

- (ArmLispCompiler*)ctor:(MACHINETYPE)i
{
	_symboltable = [[SymbolTable new] ctor];
	_typetable = [[TypeTable new] ctor];
	NSLOG(@"constructing...");
	_operatortable = [[OperatorTable new] ctor];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"+" andAddress:[[Hex alloc] ctorString:@"+"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"++" andAddress:[[Hex alloc] ctorString:@"++"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"1+" andAddress:[[Hex alloc] ctorString:@"1+"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"-" andAddress:[[Hex alloc] ctorString:@"-"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"1-" andAddress:[[Hex alloc] ctorString:@"1-"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"--" andAddress:[[Hex alloc] ctorString:@"--"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"*" andAddress:[[Hex alloc] ctorString:@"*"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"**" andAddress:[[Hex alloc] ctorString:@"**"]]];
	[_operatortable addObject:[[Operator alloc] defineWithName:@"/" andAddress:[[Hex alloc] ctorString:@"/"]]];
	//TODO add other operators
	//add arm bytecode, java bytecode, ...
	switch(i){
	case HAVE_MACHINE_6502ASM:{
		_machine = [[NesAssemblerMachine alloc] ctor];
		break; 
	}
	case HAVE_MACHINE_ARMASM:{ 
		_machine = [[ArmAssemblerMachine alloc] ctor];
		break; 
	}
	default:{
		_machine = [[ArmAssemblerMachine alloc] ctor];
		break; 
	}
	}
	NSLOG(@"done.");
	return self;
}

- (int)grepLines:(NSString*)buffer
{

	int i = -1;
	int lines = 0;
	while (++i && i < [buffer length]) {
		char c = [buffer characterAtIndex:i];
		if (c == '\n')
			lines++;	
	}
	return lines;
}

- (TupleInt*)grepWord:(FNString *)fileName withIndex:(int)idx
{
	NSString *s = @"";
	FileBuffer *buffer = [fileName buffer];

	while (++idx && idx < [buffer length]) {
		char c = [buffer characterAtIndex:idx];
		if (c == ' ' || c == '\t')
			return [[TupleInt new] addFirst:idx andSecond:s];
	
		s += c;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

- (TupleInt*)skipWhiteSpace:(NSString *)line withIndex:(int)idx
{
	NSString *s = @"";
	while (idx < [line length]) {
		char c = [line characterAtIndex:idx];
		if (c == ' ' || c == '\t')
			;
		else
			break;
		idx++;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

- (TupleInt*)searchForWeenie:(NSString *)line withIndex:(int)idx
{
	NSString *s = @"";
	while (++idx && idx < [line length]) {
		char c = [line characterAtIndex:idx];
		if (c != ';')
			;
		s += c;
	}

	return [[TupleInt new] addFirst:idx andSecond:s];
}

- (TupleInt*)grepWordOfLine:(NSString*)line withIndex:(int)idx
{
	//skip prevailing whitespace
	TupleInt *ti = [self skipWhiteSpace:line withIndex:idx];
	idx = [ti first];
	//idx--;

	NSString *s = @"";
	while (idx < [line length]) {
		char c = [line characterAtIndex:idx++];
		if (c == ' ' || c == '\t')
			return [[TupleInt new] addFirst:idx andSecond:s];
	
		s += c;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

/*
 * 1. grep word until parens encounterd '(' or ')'
 * 2. grep word starting with parens '('
 */
- (TupleInt*)grepWordOfLineParens:(NSString*)line withIndex:(int)idx
{
//	NSLOG2(@"parens s=%@",line);
//	NSLOG2(@"parens1 idx=%d",idx);
	//skip prevailing whitespace
	//int idx2 = idx; 
	TupleInt *ti = [self skipWhiteSpace:line withIndex:idx];
	//idx = [ti first];
	//if (idx2 != idx)
	//	idx--;
//	NSLOG2(@"parens2 idx=%d",idx);

	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	while (idx < [line length]) {
		char c = [line characterAtIndex:idx];
//		NSLOG2(@"parens c=%c",c);
		if (c == ' ' || c == '\t') 
			return [[TupleInt new] addFirst:idx andSecond:s];

		if ((c == '(' || c == ')') && idx > 0) {
			//s += c;
			[s appendFormat:@"%c",c];
			idx++;
			return [[TupleInt new] addFirst:idx andSecond:s];
		}
		[s appendFormat:@"%c",c];
		//s += c;
		idx++;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

/*
 * This gets a single word or form from formstring (non reversed form!) 
 */
- (NSString*)grepFormOrWord:(NSString*)formstring withIndex:(int)idx
{
	//skip prevailing whitespace
	int nopen = 0;
	int nclosed = 0;
	TupleInt *ti = [self skipWhiteSpace:formstring withIndex:idx];
	idx = [ti first];
	//Form *form = [[Form alloc] initWithString:@""];
	NSLOG3(@"grepping for wordorform in = %@ idx=%d",formstring,idx);
	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	while (idx < [formstring length]) {
		char c = [formstring characterAtIndex:idx];
		if ((c = [formstring characterAtIndex:idx]) == '(') {
			nopen++;//NOTE formstring is reversed
			[s appendFormat:@"%c",c];
		} else if ((c = [formstring characterAtIndex:idx]) == ')') {
			nclosed++;//NOTE formstring is reversed
			if (nopen == nclosed && nopen != 0 && nclosed != 0) {
				[s appendFormat:@"%c",c];
				//[form setString:s];
				//Form get formatted inherently with fomatLisp
				//in the above ctor
				NSLOG2(@"*** grepped form = %@",s);
				//return form;
				return s;
			}
		} else if (nopen == 0 && (c == ' ' || c == '\t')) { 
			//[form setString:s];
			//Form get formatted inherently with fomatLisp
			//in the above ctor
			NSLOG2(@"*** grepped word = %@",s);
			return s;
		} else {
			[s appendFormat:@"%c",c];
		}
		//s += c;
		idx++;
	}

	NSLOG2(@"*** no word or form = %@ - raise error",s);
	//Form get formatted inherently with fomatLisp
	return s;
}

- (TupleInt*)grepWordOfLineParensAndChomp:(NSString*)line withIndex:(int)idx
{
//	NSLOG2(@"parens s=%@",line);
//	NSLOG2(@"parens1 idx=%d",idx);
	//skip prevailing whitespace
	//int idx2 = idx; 
	TupleInt *ti = [self skipWhiteSpace:line withIndex:idx];
	idx = [ti first];
	//if (idx2 != idx)
	//	idx--;
//	NSLOG2(@"parens2 idx=%d",idx);

	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	while (idx < [line length]) {
		char c = [line characterAtIndex:idx];
//		NSLOG2(@"parens c=%c",c);
		if (c == ' ' || c == '\t') 
			return [[TupleInt new] addFirst:idx andSecond:s];

		if ((c == '(' || c == ')') && idx > 0)
			return [[TupleInt new] addFirst:idx andSecond:s];
		[s appendFormat:@"%c",c];
		//s += c;
		idx++;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

- (TupleInt*)getRestOfForm:(NSString*)formstring withIndex:(int)idx
{
	//FIXME ?
	//TupleInt *ti = [self skipWhiteSpace:formstring withIndex:idx];
	//idx = [ti first];
	//skip prevailing whitespace
	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	while (idx < [formstring length]) {
		char c = [formstring characterAtIndex:idx++];
		[s appendFormat:@"%c",c];
	}

	return [[TupleInt new] addFirst:idx andSecond:s];
}

- (TupleInt*)getRestOfFormAndChomp:(NSString*)formstring withIndex:(int)idx
{
	//skip prevailing whitespace
	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	while (idx < [formstring length]-1) {
		char c = [formstring characterAtIndex:idx++];
		[s appendFormat:@"%c",c];
	}

	return [[TupleInt new] addFirst:idx andSecond:s];
}

- (TupleInt*)grepWord:(NSString*)needleword OfWord:(NSString*)haystackword withIndex:(int)idx
{
	//FIXME use indexOf
	NSString *s = @"";
	while (idx++ < [haystackword length]) {
		int idx2;
		for (idx2 = 0; idx2 < [needleword length]; idx2++) {
			if ([haystackword characterAtIndex:idx+idx2] != [needleword characterAtIndex:idx2])
				break;
		}
		if ([needleword length] == idx2) {
			while (idx++ < [haystackword length])
				s += [haystackword characterAtIndex:idx];
				
			return [[TupleInt new] addFirst:idx andSecond:s];	
		}
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

/*
 * returns the line rest after needleword
 */
- (TupleInt*)grepWordOfLine:(NSString*)line withWord:(NSString*)needleword withIndex:(int)idx
{
	//skip prevailing whitespace
	//int idx2 = idx; 
	TupleInt *ti = [self skipWhiteSpace:line withIndex:idx];
	idx = [ti first];
	//if (idx2 != idx)
	//	idx--;
	//FIXME use indexOf
	NSString *s = @"";
	while (idx++ < [line length]) {
		int idx2 = 0;
		for (idx2 = 0; idx2 < [needleword length]; idx2++) {
			if ([line characterAtIndex:idx+idx2] != [needleword characterAtIndex:idx2])
				break;
		}
		if ([needleword length] == idx2) {
			while (idx++ < [line length])//concat rets of line
				s += [line characterAtIndex:idx];
				
			return [[TupleInt new] addFirst:idx andSecond:s];	
		}
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

- (NSString*)grepLine:(FNString *)fileName withIndex:(int)idx
{
	NSString *s = @"";
	FileBuffer *buffer = [fileName buffer];

	while (++idx && idx < [buffer length]) {
		char c = [buffer characterAtIndex:idx];
		if (c == '\n')
			return s;
	
		s += c;
	}

	return @"";
}
	
- (int)compilablesource:(NSString*)filename {
	
	//FileBuffer *buffer = [fileName buffer];

	//int i = -1;
	//while (++i < [buffer length]) {
	//i = [self parseFile:fileName withIndex:i];
	FNString *fn = [[FNString alloc] ctor:filename];
	[fn readInFile];
	[self parseFile:fn withIndex:0];
	//}

	return 0;
}

- (int) parseFile:(FNString*)fn withIndex:(int)idx 
{
	NSString *str = [fn bufferstring];
	
//	NSString *st;
//	st = [NSString stringWithFormat:@"str=%@", str];
//	NSLOG(st);	
	Form *f	= [[Form alloc] initWithString:str];
	if (f == nil)
		return 0;//NOTE nil form or @"" formstring
	[self parseForms:f withIndex:idx];

	return 0;
}

/*
 * This is a Lisp file's form parser, if forms
 * are encountered which can be put into the symbol or
 * type table they are transferred there with a symbol's
 * value equal to the form's code
 *
 * If the forms are to be executed they need another loop
 * through the form parser so they get executed
 * 
 * example 1 :
 * 
 * (defvar x 1 "This is the documentation of 1")
 * 
 * The form "1 "This is the documemntation of 1"" is
 * put into the symbol's name x with address [[Hex alloc] ctorString:"x"]
 * in the _symboltable of this parser. It gets immediately translated to 
 * e.g. 6502 assembly with "sta 1"
 * 
 * example 2 :
 * 
 * (defun y () (return-from "123"))
 * 
 * The only thing that happens with this is that it gets set
 * in the _symboltable with [[Hex alloc] ctorString:"y"] as an address
 */
- (int) parseForms:(Form*)form withIndex:(int)idx 
{
	NSLOG(@"parsing Forms...");
	NSString *formstring = [form string];

	int linest = [self grepLines:formstring];

	int lines = 0;
	NSString *s = [[NSString alloc] initWithString:@""];
	while (idx < [formstring length]) {
		char c = [formstring characterAtIndex:idx];	

		if (c == '\n')
			lines++;
		idx++;
	}
	Form *subform;	
	int i = 0;
	//init the top-level environment of this file's forms
	NSMutableArray* array;// = [NSMutableArray new];
	array = [self splitForms:formstring];//split
	if (array == nil /*|| [array length] == 0*/) { 
		NSLOG(@"Form array is nil@");
		return -1;
	}
	NSEnumerator *iter = [array objectEnumerator];
	//set below idx += [form length];//NOTE
	while (subform = [iter nextObject]/* && subform != nil*/) {
		[subform reverse];//NOTE
		NSLOG3(@"%@ %@", @"Processing Form",[subform string]);
		int r = [self parseFormForDefinition:subform];

		/* a definition gets added to the symbol or typetable
		 * defvar, deftype respectively
		 * deftype only generates a type in the typetable
		 * There is no machine instruction for type definitions
		 * on an ARM, 6502 etc.
                 */
		if (r == 0xdef) {//definition
			NSString *st;
			st = [NSString stringWithFormat:@"%@", @"have definition." ];	
			//[form addStatus:HAVE_DEFINITION String:st];
			NSLOG(st);
			continue;
		} else {
			r = [self parseFormForOperator:subform];
			if (r == 0xabc) {//operator
				NSString *st;
				st = [NSString stringWithFormat:@"%@", @"have operator." ];	
				//[form addStatus:HAVE_OPERATOR String:st];	
				NSLOG(st);
				continue;
			} else {
				r = [self parseFormForIf:subform];
				if (r == 0x333) {//if
					NSString *st;
					st = [NSString stringWithFormat:@"%@", @"have if." ];	
					//[form addStatus:HAVE_IF String:st];	
					NSLOG(st);
					continue;
				} else {
					r = [self parseFormForDefun:subform];
					if (r == 0xabba) {//if
						NSString *st;
						st = [NSString stringWithFormat:@"%@", @"have function definition." ];	
						//[form addStatus:HAVE_LOOP String:st];	
						NSLOG(st);
						continue;
					} else {
						r = [self parseFormForFuncall:subform];
						if (r == 0xfaa) {//if
							NSString *st;
							st = [NSString stringWithFormat:@"%@", @"have function call." ];	
							//[form addStatus:HAVE_LOOP String:st];	
							NSLOG(st);
							continue;
						}
					}
				}
			}
		}
	}
/* TODO
	if ([[fileName getLastStatus] first] == HAVE_IF) {//next subform
		subform = [self grepLine:fileName withIndex:idx];
		subform = [ self reverse: subform ];//NOTE
		int r2 = [self parseLineForElseClause:subform];
		if (r2 < 0) //no else clause found
			return idx;
		else if (r2 == 5) 
			[fileName addStatus:HAVE_ELSE String:&st];
		else if (r2 == 2) {	
			[fileName addStatus:HAVE_CLOSINGBRACE String:&st];
			[fileName addStatus:HAVE_ELSE String:&st];
		} else if (r2 == 3) {	
			[fileName addStatus:HAVE_CLOSINGBRACE String:&st];
			[fileName addStatus:HAVE_ELSE String:&st];
			[fileName addStatus:HAVE_OPENINGBRACE String:&st];
		} else {
		}
		idx += [subform length];
		[_machine pushElse:[Hex ctor: [_lastsymbol address]]];
	}
	}*/
	
	NSLOG(@"Reached end of form.");
	return 0;
}

- (int) parseAtom:(Form*)form withIndex:(int)idx 
{
	NSLOG(@"parsing Atom...");
	NSString *formstring = [form string];
		//[subform reverse];//NOTE
	NSLOG3(@"%@ %@", @"Processing Atom",[form string]);

	switch((TYPE)[self getTypeOfString:formstring]) {
	case (const TYPE)itype:
		[_machine pushLoadConstant:[[Hex alloc] ctorInt: atoi([formstring UTF8String])]];
		break;	
	case (const TYPE)symtype:
	default:{
		Hex *varhex = [[Hex new] ctorString:[form string]];
		Symbol *s2 = [_symboltable searchForHex: varhex ];
		int address;
		if (s2 == nil) 
			address = -1;
		else
			address = [[s2 address] number];
	
		//check if variable's address exists
		if (address < 0) {
			//TODO raise error
			NSLOG(@"Syntax Error (parseAtom) : unknown value of variable");
			return -1;
		} else {
			//compare address in if clause for true or false
			[_machine pushLoadSymbol:varhex];	
		}
		break;
	}
	}

/*	int r = [self parseFormForDefinition:form];
	if (r == 0xdef) {//definition
		NSString *st;
		st = [NSString stringWithFormat:@"%@", @"have definition." ];	
		//[form addStatus:HAVE_DEFINITION String:st];
		NSLOG(st);
	} else {
		r = [self parseFormForOperator:form];
		if (r == 0xabc) {//operator
			NSString *st;
			st = [NSString stringWithFormat:@"%@", @"have operator." ];	
			//[form addStatus:HAVE_OPERATOR String:st];	
			NSLOG(st);
		} else {
			r = [self parseFormForIf:form];
			if (r == 0x333) {//if
				NSString *st;
				st = [NSString stringWithFormat:@"%@", @"have if." ];	
				//[form addStatus:HAVE_IF String:st];	
				NSLOG(st);
			}
		}
	}
*/	return 0;
}

- (int) parseFormForDefinition:(Form*)form//NOTE form has been reversed reversed (human readable code string)
{

	NSLOG(@"parse for definition...");
	NSString *formstring = [form string];
	TupleInt *ti = [self grepWordOfLineParens:formstring withIndex:0 ];


	//NSLOG(@"word=%@", (NSString*)[ti second]);
	NSString *sti;
	sti = [NSString stringWithFormat:@"%@", (NSString*)[ti second]];
	//NSLOG(@"stiword=%@", sti);
	//check for type definition
	if ([sti compare: @"(deftype"] == 0) {
		NSLOG(@"deftype definition");
		//construct hex out of NSString*word which is the type after deftype
		TupleInt* ti2 = NULL;
		Tuple *t = [[Tuple new] addFirst:[ti second] andSecond:NULL ];
		NSString *word = [ t first ];
		int idx = [ti first];
		Hex *hex = [[Hex new] ctor:word];

		//check if word is already defined
		int hexint = [_typetable searchForHex: hex];//TODO return Type* instead of hexint

		//NOTE FIXME big endian system, bit per bit parsing of ids
		//check if hex needs updating

		//NOTE do not forget Lisp changes its native types, so type in typetable needs to be overwritten
		while (hexint != 0x0000) {
			int h = h | hexint;
			//switch on Native Lisp type (integer, char, ...) 
			switch (hexint & 0x1000) {
			case (const TYPE)ctype:{//ctype, character type
				continue;
				break;
			}
			case (const TYPE)itype:{//itype const, integer
				
				if ([[self parsehexandset: h] first] == 0x0000) 
					continue; 
				else {// hex is e.g. 0x02 for int (itype) 
					ti2 = [self grepWordOfLineParens:formstring withIndex:[ti first]];
					idx = [ti2 first];
					[self parseDefinitionOfdeftype:ti2];
					//goto lableassignment;
				}
				break;
			}
			//FIXME vtype 4 and other types
			default:{
				break;
			}
			}
			hexint <<= 2;
	
		}
		return 0xdef;
	} else if ([sti compare: @"(defvar"] == 0) {
		NSLOG(@"defvar definition");
		//NSLOG2(@"1--->%@",[ti second]);

		TupleInt* ti2;
		TupleInt* ti3;
		TupleInt* ti4;
		
		//example : (defvar x 1)
		//get name of free variable (x)
		ti2 = [self grepWordOfLineParens:formstring withIndex:[ti first]];
		//NSLOG3(@"2--->%@ idx=%d",[ti2 second],[ti2 first]);
		ti4 = [self getRestOfForm:formstring withIndex:[ti2 first]];
		//get value of free variable (1)
		//NSLOG2(@"rest of form--->%@",[ti4 second]);
		TupleInt *ti5 = [self hasSubForms:[ti4 second]];
		if ([ti5 first] < 0) {
			ti3 = [self grepWordOfLineParensAndChomp:formstring withIndex:[ti2 first]];
			//NSLOG2(@"5--->%@",[ti3 second]);
			[self parseDefinitionOfdefvar:ti2 and:ti3];//evals to formstring or simple statement
		} else {
			ti3 = [self getRestOfFormAndChomp:formstring withIndex:[ti2 first]];
			//NSLOG2(@"5--->%@",[ti3 second]);
			[self parseDefinitionOfdefvarWithForm:ti2 and:ti3];//evals to formstring or simple statement
		} 
		return 0xdef;
	} else if ([sti compare: @"(setq"] == 0 || [sti compare: @"(setf"] == 0) {
		NSLOG(@"setq or setf definition");

		TupleInt* ti2;
		TupleInt* ti3;
		TupleInt* ti4;
		TupleInt* ti5;
		
		ti3 = [self skipWhiteSpace:formstring withIndex:[ti first]];
		//example : (setq x 1)
		//get name of free variable (x)
		ti2 = [self grepWordOfLineParens:formstring withIndex:[ti3 first]];
		NSLOG2(@"definition sym=%@ ",[ti2 second]);
		ti4 = [self getRestOfFormAndChomp:formstring withIndex:[ti2 first]];
		//get value of free variable (1)
		//evals to formstring or simple statement
		//ti5 = [self hasSubForms:[ti4 second]];
		NSString *s5 = [self grepFormOrWord:formstring withIndex:[ti2 first]];
		NSLOG2(@"definition sym5=%@ ",s5);
		if ([s5 characterAtIndex:0] != '(') {
			//ti3 = [self grepWordOfLineParensAndChomp:formstring withIndex:[ti2 first]];
			NSLOG3(@"def sym=%@ val=%@",[ti2 second],[ti4 second]);
			[self parseDefinitionOfsetfq:ti2 and:ti4];
		} else {
			ti3 = [self getRestOfFormAndChomp:formstring withIndex:[ti2 first]];
			[self parseDefinitionOfsetfqWithForm:ti2 and:ti4];//evals to formstring or simple statement
		} 

		return 0xdef;
	} else {
		NSLOG(@"No definition");
		return 0x000;//NOTE
	}
	return 0x000;//NOTE
}

- (int) parseFormForOperator:(Form*)form//NOTE line has been reversed reversed
{
	NSLOG(@"parsing for operator...");
	NSString *formstring = [form string];
	int idx = 0;

	while (idx++ < [formstring length]) {

		TupleInt *ti = [self grepWordOfLineParens:[form string] withIndex:1];//NOTE 1
		idx = [ti first];
		Operator *op = [_operatortable getOperator:[ti second]];
		if (op == nil) {//Operator does not exist, no definition or declaration found
			NSLOG(@"no matching operator not found");
			return 0x000;
		} 

		//NOTE rest of form is even parensed by splitForms: above
		ti = [self getRestOfForm:formstring withIndex:idx];
		//idx = [ti first];
		NSLOG2(@"rest of form=%@", [ti second]);	

	
		return [self parseOperator:[op string] form:[[Form alloc] initWithString:[ti second]]];
	}
	return 0x000;
}

- (int) parseLineForAssignmentWithOperator:(NSString*)line//NOTE line has been reversed reversed
{
	TupleInt *ti = [self grepWordOfLine:line withIndex:0];
	int idx = [ti first];
	if ([ti second] == @"") {
		return 0x000;
	}
	Symbol *s = [_symboltable getString:[ti second]];
	if (s == NULL) {//Symbol does not exist, no definition or declaration found
		return 0x000;
	} else {
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:s];
	}

	ti = [self grepWordOfLine:line withIndex: idx];
	idx = [ti first];

	if ([ti second] != @"=" || [ti second] == @"==") {
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove

		return 0x0000;
	} 
	
	while (++idx && idx < [line length] && [line characterAtIndex:idx] != ';') {

		ti = [line grepWordOfLine:line withIndex:idx];
		idx = [ti first];
		Symbol *s = [_symboltable getString:[ti second]];//FIXME numbers instead of symbols
		if (s == NULL) {//Symbol does not exist, no definition or declaration found
			return 0x000;
		} else if ( [self checkTypeOf:s and:[[_parsetreestatus second] type]] < 0 ) {
			//invalid return/previous type	
			return 0x0000;	

		} else {
			_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:s];
		}
	
		ti = [line grepWordOfLine:line withIndex:idx];
		idx = [ti first];

		[self parseOperator:[ti second] withAddress:[Hex ctor:[[ti second] address]] andAddress:[Hex ctor: [s address]]];
	}
	_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove
	int weenieidx = [[self searchForWeenie:line withIndex:idx] first];
	if (idx < [line length] && idx <= weenieidx)
		return 0xabc;
 
	if (weenieidx >= [line length])
			return 0x000;//FIXME addError

	return 0x000;
}

- (int) parseLineForAssignment:(NSString*)line//NOTE line has been reversed reversed
{
		
	_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove

}

- (int) parseFormForDefun:(Form*)form//NOTE line has been reversed reversed
{
	TupleInt* ti = [self grepWordOfLineParens:[form string] withIndex:0];
	Word *w = [[Word alloc] ctor: [ti second]];//NOTE form
	NSLOG3(@"-------------->%@ is=%d", [w string],[w isParensDefun]);
	//if ([w isParensDefun] < 0) {	
	if ([[w string] compare: @"(defun"] != 0) {
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove
		return 0x000;
	}

	if ([self parseFormForDefunClause:[[Form alloc] initWithString:[form string]]] == 0xabba) {
		//[_machine pushPreviousLabel];
		NSString *l = [_machine getLastLabel];//FIXMENOTETODO!!
		[_machine pushLoopGoto:l];
		
		return 0xabba;
	}
}

- (int) parseFormForIf:(Form*)form//NOTE line has been reversed reversed
{
	TupleInt* ti = [self grepWordOfLineParens:[form string] withIndex:0];
	Word *w = [[Word alloc] ctor: [ti second]];//NOTE form

	if ([w isParensIf] < 0 || [w isIfClause] < 0) {	
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove
		return 0x000;
	}

	if ([self parseFormForIfClause:[[Form alloc] initWithString:[form string]]] == 0x333) {
		//[_machine pushPreviousLabel];
		
		return 0x333;
	}
}

- (int) parseFormForLoop:(Form*)form//NOTE line has been reversed reversed
{
	TupleInt* ti = [self grepWordOfLineParens:[form string] withIndex:0];
	Word *w = [[Word alloc] ctor: [ti second]];//NOTE form

	if ([w isParensLoop] < 0 /*|| [w isIfClause] < 0*/) {	
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove
		return 0x000;
	}

	if ([self parseFormForLoopClause:[[Form alloc] initWithString:[form string]]] == 0x444) {
		//[_machine pushPreviousLabel];
		
		return 0x444;
	}
}

- (int) parseLineForWhile:(NSString*)line//NOTE line has been reversed reversed
{
	Word *w = [Word ctor: line];//NOTE line

	if ([w isWhile] < 0 || [w isWhileClause] < 0) {	
		_parsetreestatus = [[TupleInt new] addFirst:0 andSecond:NULL];//FIXME remove
		return 0x000;
	}

	[_machine pushNewLabel];
	if ([self parseLineForWhileClause:line] == 0x444) {
		[_machine pushBranch:[Hex ctor: [_lastsymbol address]]];
		
		return 0x444;
	}
}

- (int) parseFormForFuncall:(Form*)form
{
	NSLOG(@"Parsing Funcall");
	//skip leading '(', idx = 1 here
	Form *f = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:1]];
	//int idx = [self skipWordAndWhiteSpace:form withIndex:0];
	//TupleInt* ti = [self grepWordOfLineParens:[f string] withIndex:0];
	
	Hex *varhex = [[Hex new] ctorString:[f string]];
	Symbol *s = [_symboltable searchForHex: varhex ];
	//Symbol *s = [_symboltable getString:[f string]];

	//generate loop label and push it
	//[_machine pushNewLabel];
	//NSString *looplabel = [_machine getLastLabel];
	NSLOG2(@"func symbol found=%@",[s string]);
	//Form *f = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];

	if ([s type] == (TYPE)functype) {
		NSLOG(@"got function symbol");

		Form *argsandbody = [s value];
		NSLOG2(@"argsandbody = %@", [s value]);
		// index 1, skip '('
		NSString *args = [self grepFormOrWord:argsandbody withIndex:0];

		int idx = 1;
		int idx2 = [self skipWordAndWhiteSpace:form withIndex:0];
		while (idx2 < [[form string] length]-1) {//-1 index for last ')'

			//argument symbol name
			TupleInt *ti = [self grepWordOfLineParensAndChomp:args withIndex:idx];//TODO AndChomp for several args
			idx = [ti first];
			//argument value
			NSString *argvalue = [self grepFormOrWord:[form string] withIndex:idx2];
			//idx = [self skipFormAndWhiteSpace:form withIndex:idx];
			NSLOG2(@"symvalue = %@", [ti second]);
			NSLOG2(@"argvalue = %@", argvalue);
			//Hex *vargulf = [[Hex new] ctorString:[s2 string]];

			[self parseDefinitionOfdefvar:[[TupleInt alloc] addFirst:-1 andSecond:[ti second]] and:[[TupleInt alloc] addFirst:-1 andSecond:argvalue]];
			//[_machine pushDefinition:varhex with:vargulf];

			idx2 = [self skipWordAndWhiteSpace:form withIndex:idx2];
		}
		//push label to go to function call
		NSString *newl = [_machine generateFreeLabel];
		NSString *functionlabel = [NSString stringWithFormat:@"label%@",[s name]];
		[_machine pushLoopGoto:functionlabel];

		[_machine pushNewLabel:newl];

		return 0xfaa;
	}

	return 0x000;
}

- (int) parseFormForLoopClause:(Form*)form
{
	//generate loop label and push it
	[_machine pushNewLabel];
	NSString *looplabel = [_machine getLastLabel];
	
	int idx = [self skipWordAndWhiteSpace:form withIndex:0];
	NSLOG2(@"P=%d",idx);
	Form *f = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];

	if ([[f string] compare: @"while"] == 0) {

		NSLOG(@"got Loop while");

		//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
		//loop condition is atom
		//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
		NSLOG3(@"form string=%@ idx=%d",[form string], idx);
		idx = [self skipWordAndWhiteSpace:form withIndex:idx];
		Form *f2 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
		if ([[f2 string] characterAtIndex:0] != '(') {
			//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			//Form *f2 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			[self parseAtom:f2 withIndex:0];	

			[_machine pushLoopDefaultRegister];

			idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			NSLOG2(@"W=%d",idx);
			TupleInt* ti = [self grepWordOfLine:[form string] withIndex:idx];
			NSLOG2(@"W=%d",[ti first]);
			//if ([[ti second] compare: @"do"] == 0) {
				//TODO != '(', isForm
				NSLOG(@"do of loop");
				idx = [self skipWordAndWhiteSpace:form withIndex:idx];
				Form *f3 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				//[f3 reverse];
				if ([[f3 string] characterAtIndex:0] != '(') {	
					[self parseAtom:f3 withIndex:0];	
					[_machine pushLoopGoto:looplabel];
					[_machine pushPreviousLabel];

				} else {

					[self parseForms:f3 withIndex:0];	
					[_machine pushLoopGoto:looplabel];
					[_machine pushPreviousLabel];
				}
			return 0x444;
			//}
		} else {
		//loop condition is form
			//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			Form *f4 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			[f4 reverse];
			[self parseForms:f4 withIndex:0];	

			[_machine pushLoopDefaultRegister];

			idx = [self skipFormAndWhiteSpace:form withIndex:idx];
			NSLOG2(@"WW=%d",idx);
			TupleInt* ti = [self grepWordOfLine:[form string] withIndex:idx];
			NSLOG2(@"WW=%d",[ti first]);
			NSLOG(@"do of loop form");
			//skip do word
			idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			Form *f3 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			if ([[f3 string] characterAtIndex:0] != '(') {	
				[self parseAtom:f3 withIndex:0];	
				[_machine pushLoopGoto:looplabel];
				[_machine pushPreviousLabel];

			} else {

				[self parseForms:f3 withIndex:0];	
				[_machine pushLoopGoto:looplabel];
				[_machine pushPreviousLabel];
			}
			return 0x444;
		}

	}
	return 0x000;
}

- (int) parseFormForDefunClause:(Form*)form
{
	NSLOG(@"Parsing Defun Clause");



	int idx = [self skipWordAndWhiteSpace:form withIndex:0];
	Form *funname = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
	//if ([f isForm] < 0) {

	//pushing function label
	NSString *ns = [NSString stringWithFormat:@"label%@:",[funname string]];
	[_machine pushNewLabel:ns];

	idx = [self skipWordAndWhiteSpace:form withIndex:idx];
	Form *arglist = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];

	TupleInt *ti = [self getRestOfForm:[form string] withIndex:idx]; 

	idx = [self skipFormAndWhiteSpace:form withIndex:idx];
	Form *funbody = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];

	//Symbol *s = [[Symbol alloc] ctorName:[funname string] form:funbody type:(TYPE)functype];
	Symbol *s = [[Symbol alloc] ctorName:[funname string] form:[ti second] type:(TYPE)functype];
	[_symboltable addObject:s];
	//FIXME_lastsymbol = s;
	NSLOG4(@"defunname=%@ defunbody=%@ type=%d",[funname string],[ti second],functype);

/*
	while (idx < [arglist string]) { 
		NSLOG(@"parsing function argument list");
		NSString *st = [self grepWordOfLineParens:[arglist string] withIndex:idx];
		idx = [self skipWordAndWhiteSpace:form withIndex:idx];
		Hex *varhex = [[Hex new] ctorString:[arglist string]];
		Symbol *s2 = [_symboltable searchForHex: varhex ];
		[_machine pushLoadSymbol:varhex];
	}
*/

	//idx = [self skipFormAndWhiteSpace:form withIndex:idx];
	if ([[funbody string] characterAtIndex:0] != '(') {
		[self parseAtom:funbody withIndex:0];
		return 0xabba;
	} else {
		[funbody reverse];
		[self parseForms:funbody withIndex:0];
		return 0xabba;
	}

	return 0x000;

}

- (int) parseFormForIfClause:(Form*)form
{
	NSLOG(@"Parsing If Clause");
	int idx = [self skipWordAndWhiteSpace:form withIndex:0];
	NSLOG2(@"P=%d",idx);
	Form *f = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
	NSLOG2(@"ISFORM=%@",[f string]);
	//if ([f isForm] < 0) {
	if ([[f string] characterAtIndex:0] != '(') {
		//found symbol or value
		//if ([_lastsymbol isKindOfClass:[Symbol class]]) {
		switch ((TYPE)[self getTypeOfString: [f string]]) {
		case (const TYPE)itype:
			[_machine pushIfConstant:atoi([[f string] UTF8String])];//TODO use value to type value conversion within Symbol
			//TODO parsing of true and false clauses	
			break;
		case (const TYPE)symtype:
		default:{
			Hex *varhex = [[Hex new] ctorString:[f string]];
			Symbol *s2 = [_symboltable searchForHex: varhex ];
			int address;
			if (s2 == nil) 
				address = -1;
			else
				address = [[s2 address] number];
	
			//check if variable's address exists
			if (address < 0) {
				//TODO raise error
				NSLOG(@"Syntax Error : unknown value of variable");
				return -1;
			} else {
				//compare address in if clause for true or false
				[_machine pushIf:[[Hex alloc] ctorInt: address]];
			}
		}	
		}//switch
		idx = [self skipWordAndWhiteSpace:form withIndex:idx];
		NSLOG2(@"P=%d",idx);
		Form *ff = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
		
		//if ([f isForm] < 0) {
		//true clause is not a form
		if ([[ff string] characterAtIndex:0] != '(') {
			[self parseAtom:ff withIndex:0];

			idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			NSLOG2(@"P=%d",idx);
			Form *fff = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			
			if ([[fff string] compare:@""] == 0 || [[fff string] compare:@")"] == 0 || [[fff string] compare:@"\n"] == 0) {
				NSLOG(@"* no else clause");
				return 0x333;	
			}
			//if ([f isForm] < 0) {
			//else clause is not a form

			if ([[fff string] characterAtIndex:0] != '(') {
				[_machine pushPreviousLabel];
				[self parseAtom:fff withIndex:0];
				return 0x333;
			} else {//else clause is form
				[_machine pushPreviousLabel];
				[self parseForms:fff withIndex:0];
				return 0x333;
			}
		} else {//true clause is form
			NSLOG2(@"ff str=%@", [ff string]);
			[ff reverse];//FIXMENOTETODO
			[self parseForms:ff withIndex:0];
			[_machine pushPreviousLabel];

			idx = [self skipFormAndWhiteSpace:ff withIndex:idx];
			Form *form4 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
		
			NSLOG2(@"form4 string=%@",[form4 string]);
	
			/*if ([[form4 string] compare:@""] == 0 || [[form4 string] compare:@")"] == 0 || [[form4 string] compare:@"\n"] == 0) {
				NSLOG(@"* no else clause");
				return 0x333;	
			}*/
			//else clause is not a form
			//if ([f isForm] < 0) {
			if ([[form4 string] characterAtIndex:0] != '(') {
				idx = [self skipWordAndWhiteSpace:ff withIndex:idx];
				//Form *form11 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				//[form11 reverse];
				//[self parseForms:form11 withIndex:0];
				[self parseAtom:form4 withIndex:0];
				return 0x333;
			} else {//else clause is form
				idx = [self skipFormAndWhiteSpace:form withIndex:idx];
				Form *form10 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				[form10 reverse];
				[self parseForms:form10 withIndex:0];
				return 0x333;
			}
			return 0x333;
		}
	} else {//if clause is form
		NSLOG2(@"if clause is form=%@", [f string]);
		[f reverse];
		[self parseForms:f withIndex:0];
		[_machine pushIfDefaultRegister];
		NSLOG2(@"f =%@",[f string]);
		idx += [[f string] length];
		idx = [self skipWordAndWhiteSpace:form withIndex:idx];
		NSLOG2(@"P=%d",idx);
		Form *ff = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
		
		//true clause is atom	
		//if ([f isForm] < 0) {
		if ([[ff string] characterAtIndex:0] != '(') {
			[self parseAtom:ff withIndex:0];
			[_machine pushPreviousLabel];
			idx = [self skipFormAndWhiteSpace:ff withIndex:idx];
			//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			Form *form5 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			
			if ([[form5 string] compare:@""] == 0 || [[form5 string] compare:@")"] == 0 || [[form5 string] compare:@"\n"] == 0) {
				NSLOG(@"* no else clause");
				return 0x333;	
			}
			//else clause is not a form
			//if ([f isForm] < 0) {
			if ([[form5 string] characterAtIndex:0] != '(') {
				NSLOG2(@"form5 atom string=%@",[form5 string]);
				[self parseAtom:form5 withIndex:0];
				idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
				Form *form9 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				[form9 reverse];
				[self parseForms:form9 withIndex:0];
				return 0x333;
			} else {//else clause is form
				NSLOG2(@"form5 form string=%@",[form5 string]);
				idx = [self skipFormAndWhiteSpace:form withIndex:idx];
			//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
				Form *form6 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				[self parseForms:form6 withIndex:0];
				return 0x333;
			}
		//true clause is form
		} else {
			[ff reverse];
			[self parseForms:ff withIndex:0];
			[_machine pushPreviousLabel];
			//idx = [self skipWordAndWhiteSpace:form withIndex:idx];
			idx = [self skipFormAndWhiteSpace:form withIndex:idx];
			Form *form5 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			
			if ([[form5 string] compare:@""] == 0 || [[form5 string] compare:@")"] == 0 || [[form5 string] compare:@"\n"] == 0) {
				NSLOG(@"* no else clause");
				return 0x333;	
			}
			//else clause is not a form
			NSLOG3(@"--------->%@ idx=%d",[form5 string],idx);
			Form *form6 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
			//if ([f isForm] < 0) {
			if ([[form6 string] characterAtIndex:0] != '(') {
				Form *form7 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				[self parseAtom:form7 withIndex:0];
				idx = [self skipWordAndWhiteSpace:form withIndex:idx];
				Form *form8 = [[Form alloc] initWithString:[self grepFormOrWord:[form string] withIndex:idx]];
				if ([[form8 string] characterAtIndex:0] != '(') {
					[self parseAtom:form7 withIndex:0];
				}
				return 0x333;
			} else {//else clause is form
				[form6 reverse];
				[self parseForms:form6 withIndex:0];
				return 0x333;
			}
		}
		return 0x333;
	}
	
	//}
	//}
//	[_machine pushIf:[[Hex alloc] ctorInt: [[_lastsymbol address] number]]];
//		return 0x333;
/*	 else {
		if ([_machine type] != HAVE_MACHINE_6502ASM)
			[_machine pushIfDefaultRegister];//TODO
		return 0x000;
	}
*/
/*	r = [self parseLineForAssignmentWithOperator:[form string]];
	if (r == 0xabc) {//assignment with op 
		[_machine pushIf:[Hex ctor: [_lastsymbol address]]];
		return 0x333;
	}
*/
	return 0x000;
}
/*
- (int) parseLineForElseClause:(NSString*)line
{
	TupleInt *ti = [self skipWhiteSpace:line withIndex:0];
	int idx = [ti first];

	while (idx < [line length]){
	switch ([line characterAtIndex:idx++]){
	case '}':{
		continue;	
		break;
	}
	case ' ':{
		continue;	
		break;
	}
	default:{
		Word *w4 = [Word ctor:line];
		if ([w4 isElseClause]) {
			return [w4 isElseClause];

	} else {//if clause is form
		NSLOG2(@"is form = %@",[f string]);
		[f reverse];
		[self parseForms:f withIndex:0];
		[_machine pushIfDefaultRegister];
		return 0x333;
	}
	//}
	//}
//	[_machine pushIf:[[Hex alloc] ctorInt: [[_lastsymbol address] number]]];
//		return 0x333;
*//*	 else {
		if ([_machine type] != HAVE_MACHINE_6502ASM)
			[_machine pushIfDefaultRegister];//TODO
		return 0x000;
	}
*/
/*	r = [self parseLineForAssignmentWithOperator:[form string]];
	if (r == 0xabc) {//assignment with op 
		[_machine pushIf:[Hex ctor: [_lastsymbol address]]];
		return 0x333;
	}
*/
/*	return 0x000;
}*/

- (int) parseLineForElseClause:(NSString*)line
{
	TupleInt *ti = [self skipWhiteSpace:line withIndex:0];
	int idx = [ti first];

	while (idx < [line length]){
	switch ([line characterAtIndex:idx++]){
	case '}':{
		continue;	
		break;
	}
	case ' ':{
		continue;	
		break;
	}
	default:{
		Word *w4 = [Word ctor:line];
		if ([w4 isElseClause]) {
			return [w4 isElseClause];
		}

		Word *w = [Word ctor:[[self grepWordOfLine:line withIndex:idx] second]];
		Word *w2 = [Word ctor:[[self grepWordOfLine:line withIndex:idx] second]];
		Word *w3 = [Word ctor:[[self grepWordOfLine:line withIndex:idx] second]];
		if ([w isElse]) {
			//goto lablepif;
			Word *w = [Word ctor:[self grepWordOfLine:line withIndex:idx]];
			return idx;
		} else if ([w isClosingBrace]) {
			if ([w2 isElse]) {
				if ([w3 isOpeningBrace])
					return 3;
				else
					return 2;
			}
		} else if ([ w2 isElse]) {
			return 5;
		}
		return 4;	
		break;
	}
	}
	}
	return -1;
	
//lablepif:

	////if ([w isClosingBrace] >= 0)
			
	return idx;
}
 
- (int)parseOperator:(NSString*)op form:(Form*)form
{

	int idx = 0;
	//NOTE skip '('
	//idx++;

	switch ([op characterAtIndex: 0]) {//character as e.g. '+', (in op string!)
	case '1':
	case '+':{
		//++,1+
		if ([op length] > 1) {
			//skip op
			idx ++;
			if ( [op characterAtIndex: 1] == '+') {//NOTE e.g. i++
			//[_machine pushOperatorPlusPlus:addr];
				//[self setLastSymbol:s];
				return 0xabc;
			}
		//+
		} else if ([op characterAtIndex:0] != '1') {
			//skip operator syntax '+'
			//idx++;
			//skip whitespace 
			//idx++;
			NSLOG2(@"with idx : %@",[form string]);
			TupleInt *ti = [self skipWhiteSpace:[form string] withIndex:idx];
			idx = [ti first];
			NSLOG2(@"with idx : %@",[ti second]);
			//TupleInt *ti5 = [self hasSubForms:[form string]];
			//if ([ti5 first] < 0) {
			NSString *s5 = [self grepFormOrWord:[form string] withIndex:idx];
			if ([s5 characterAtIndex:0] != '(') {
			//if ([[self hasSubForms:[form string]] first] < 0) {
				while (idx < [[form string] length]-1) {//-1 skip last parens
					TupleInt *ti = [self grepWordOfLineParensAndChomp:[form string] withIndex:idx];
					NSLOG2(@"with idx : %@",[ti second]);
					idx = [ti first];

					if ([self parsePlus:ti] != 0)
						return -1;
					idx++;
				}
				return 0xabc;
			} else {//if ([[self hasSubForms:[form string]] first] == 1) {
			TupleInt *ti5 = [self hasSubForms:[form string]];
			if ([ti5 first] < 0) {

				while (idx < [[form string] length]-1) {
					TupleInt *ti = [self grepWordOfLineParensAndChomp:[form string] withIndex:idx];
					idx = [ti first];

					if ([self parsePlus:ti] != 0)
						return -1;
					idx++;
				}	
				return 0xabc;

			}
			}	
		}
		break;
	}
	}

	switch ([op characterAtIndex: 0]) {//character as e.g. '+'
	case '1':
	case '-':{
		//--,1-
		if ([op length] > 1) {
			idx ++;
			if ( [op characterAtIndex: 1] == '-') {//NOTE e.g. i++
			//[_machine pushOperatorPlusPlus:addr];
			}
		//+
		} else if ([op characterAtIndex:0] != '1') {
			TupleInt *ti = [self skipWhiteSpace:[form string] withIndex:idx];
			idx = [ti first];
			TupleInt *ti5 = [self hasSubForms:[form string]];
			if ([ti5 first] < 0) {
				while (idx < [[form string] length]-1) {
					TupleInt *ti = [self grepWordOfLineParensAndChomp:[form string] withIndex:idx];
					idx = [ti first];

					if ([self parseMin:ti] != 0)
						return -1;
					idx++;
				}
				return 0xabc;
			}	
		}
		break;
	}
	case '*':{
		//**
		if ([op length] > 1) {
			idx ++;
			if ( [op characterAtIndex: 1] == '*') {//NOTE e.g. i++
			//[_machine pushOperatorMulMul:addr];
			}
		//*
		} else {
			TupleInt *ti = [self skipWhiteSpace:[form string] withIndex:idx];
			idx = [ti first];
			TupleInt *ti5 = [self hasSubForms:[form string]];
			if ([ti5 first] < 0) {
			//if ([[self hasSubForms:[form string]] first] < 0) {
				while (idx < [[form string] length]-1) {
					TupleInt *ti = [self grepWordOfLineParensAndChomp:[form string] withIndex:idx];
					idx = [ti first];

					if ([self parseMul:ti] != 0)
						return -1;
					idx++;
				}
				return 0xabc;
			}	
		}
		break;
	}
/*	case '|':{
		if ([op length] > 1 && [op characterAtIndex: 1] == '|')//NOTE || 
			;//[_machine pushOperatorOr:addr];//e.g. || 
		else
			;//[_machine pushOperatorBitwiseOr:addr];
		break;
	}
	case '&':{
		if ([op length] > 1 && [op characterAtIndex: 1] == '&')//NOTE || 
			;//[_machine pushOperatorAnd:addr];//e.g. || 
		else
			;//[_machine pushOperatorBitwiseAnd:addr];
		break;
	}
	case '^':{
		//[_machine pushOperatorBitwiseExclusiveOr:addr];
	}
*/	default:{
		break;
	}
	}

	return 0x000;
}
/*
- (int)parseOperator:(NSString*)op withAddress:(int)addr andAddress:(int)addr2
{
		switch ([op characterAtIndex: 0]) {//character as e.g. '+'
		case '+':{
			if ([op length] > 1 && [op characterAtIndex: 1] == '+')//NOTE e.g. i++
				[_machine pushOperatorPlusPlus:addr];
			else if ([op length] > 1 && [op characterAtIndex: 1] == '=')//NOTE e.g. i++
				[_machine pushOperatorPlusAssign:addr andAddress:addr2];//e.g. addr += addr2
			else
				[_machine pushOperatorPlus:addr];
			break;
		}
		case '-':{
			if ([op length] > 1 && [op characterAtIndex: 1] == '-')//NOTE e.g. i--
				[_machine pushOperatorMinusMinus:addr];
			else if ([op length] > 1 && [op characterAtIndex: 1] == '=')//NOTE e.g. i++
				[_machine pushOperatorMinusAssign:addr andAddress:addr2];//e.g. addr += addr2
			else
				[_machine pushOperatorMinus:addr];
			break;
		}
		case '|':{
			if ([op length] > 1 && [op characterAtIndex: 1] == '|')//NOTE e.g. i++
				[_machine pushOperatorOr:addr];
			else if ([op length] > 1 && [op characterAtIndex: 1] == '=')//NOTE e.g. i++
				[_machine pushOperatorBitwiseOrAssign:addr andAddress:addr2];//e.g. addr |= addr2
			else
				[_machine pushOperatorBitwiseOr:addr];
			break;
		}
		case '&':{
			if ([op length] > 1 && [op characterAtIndex: 1] == '&')//NOTE e.g. i++
				[_machine pushOperatorAnd:addr];
			else if ([op length] > 1 && [op characterAtIndex: 1] == '=')//NOTE e.g. i++
				[_machine pushOperatorBitwiseAndAssign:addr andAddress:addr2];//e.g. addr |= addr2
			else
				[_machine pushOperatorBitwiseAnd:addr];
			break;
		}
		case '^':{
			if ([op length] > 1 && [op characterAtIndex: 1] == '=')//NOTE e.g. i++
				[_machine pushOperatorBitwiseExclusiveOrAssign:addr andAddress:addr2];//e.g. addr |= addr2
			else
				[_machine pushOperatorBitwiseExclusiveOr:addr];
			break;
		}
		default:{
			break;
		}
		}
	return 0;
}
*/
- (TYPE)checkTypeOf:(Symbol*)sym and:(TYPE)t
{

	if ([sym type] == t)
		return t;

	if (([sym type] == ctype && t == itype) 
		|| 
		(t == ctype && [sym type] == itype)) 
		return itype;

	if ([_typetable hasType: [sym type]]) {//t is not used
		return [sym type];
	} 

	return -1;
}

- (TYPE)getTypeOfString:(NSString*)s
{
	NSLOG2(@"TYPE2=%@",s);
	if ([s compare: @"0"] != 0 && atoi([s UTF8String]) > 0) {
		NSLOG2(@"atoi=%d",atoi([s UTF8String]));
		return itype;
	}
	else if ([s compare: @"0"] != 0 && atof([s UTF8String]) > 0)
		return ftype;
	//character type also things like #\Linefeed
	else if ([s length] == 3 && [s characterAtIndex:0] == '#'
				 && [s characterAtIndex:1] == '\\'
				 && isascii([s characterAtIndex:2])) {
		return ctype;
	} else if ([s length] > 0 && [s characterAtIndex:0] == '"'
				&& [s characterAtIndex:[s length]-1] == '"')
		return stype;
	 else if ([s length] > 0)//TODO return -1 below
		return symtype;
	
/*
	if ([_typetable hasType: [s type]]) {//t is not used
		return [s type];
	} 
*/
	return -1;
}

- (TupleInt*) parsehexandset:(int)h 
{
	//big endian system
	switch (h) {
	case 0x00:{
		return 0;
	}
	case (const TYPE)ctype:{//ctype
		_parsetreestatus = [[TupleInt new] addFirst:ctype andSecond:@"char"]; 	
		break;
	}
	case (const TYPE)itype:{//itype
		_parsetreestatus = [[TupleInt new] addFirst:itype andSecond:@"integer"]; 	
		break;
	}
	case (const TYPE)vtype:{//vtype
		_parsetreestatus = [[TupleInt new] addFirst:vtype andSecond:@"void"]; 	
		break;
	}
	default:{
	}
	}	
	return _parsetreestatus;
}

- (int) parseDefinitionOfdeftype:(TupleInt*)status
{
	/*
	 * There is no machine instruction for type definitions
	 * on an ARM, 6502 etc.
	 * If a Lisp type gets encountered elsewhere the _typetable
	 * again provides help
         */
	int val = NULL;
	int addy = [_machine generateFreeAddress];
	[_typetable addType:addy withName:[status second]];
	[_machine pushDefinition:[[Hex new]setNumber:addy] with:[[Hex new]setNumber:val]];
	return 0;
}

- (int) parseDefinitionOfdefvar:(TupleInt*)sym and:(TupleInt*)val
{
	//TODO optional documentation string
	//TODO types of [var second] which is nto a form
	Hex *varhex = [[Hex new] ctorString:[sym second]];
	Hex *vargulf = [[Hex new] ctorInt:atoi([[val second] UTF8String])];

	NSLOG4(@"vars = %d %d val=%@",[varhex number],[vargulf number],[val second]);

	Symbol *s2 = [_symboltable searchForHex: varhex ];
	int address;
	if (s2 == nil) 
		address = -1;
	else
		address = [[s2 address] number];
	Symbol *s;
	//generate a new Hex _address, if _symboltable does not contain hexnumber address
	if (address < 0) {//var does not already exist 
		NSLOG(@"defvarAtom : no address found");
		address = [_machine generateFreeAddress];
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ctype];
			break;
		case (const TYPE)itype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:itype];
			break;
		case (const TYPE)stype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:stype];
			break;
		case (const TYPE)ftype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			
			break;
		}

		[_symboltable addObject:s];

	} else {

		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ctype];
			break;
		case (const TYPE)itype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:itype];
			break;
		case (const TYPE)stype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:stype];
			break;
		case (const TYPE)ftype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		}
	}
	[self setLastSymbol:s];
	//add symbol
	[_machine pushDefinition:varhex with:vargulf];//FIXME value NSString to number

	return 0;
}

//Form in [val second] gets assigned to variable
- (int) parseDefinitionOfdefvarWithForm:(TupleInt*)sym and:(TupleInt*)val
{
	//TODO optional documentation string
	Hex *varhex = [[Hex new] ctorString:[sym second]];

	//NSLOG3(@"vars = %d val=%@",[varhex number],[val second]);

	Symbol *s2 = [_symboltable searchForHex: varhex ];
	int address;
	if (s2 == nil) 
		address = -1;
	else
		address = [[s2 address] number];
	Symbol *s;
	//generate a new Hex _address, if _symboltable does not contain hexnumber address
	if (address < 0) {//var does not already exist 
		NSLOG(@"defvarForm : no address found");
		address = [_machine generateFreeAddress];
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ctype];
			break;
		case (const TYPE)itype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:itype];
			break;
		case (const TYPE)stype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:stype];
			break;
		case (const TYPE)ftype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			
			break;
		}
		[_symboltable addObject:s];
	} else {
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ctype];
			break;
		case (const TYPE)itype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:itype];
			break;
		case (const TYPE)stype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:stype];
			break;
		case (const TYPE)ftype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		}

	}
	[self setLastSymbol:s];

	return 0;
}

- (int) parseDefinitionOfsetfq:(TupleInt*)sym and:(TupleInt*)val
{
	//TODO optional documentation string
	//TODO types of [var second] which is nto a form
	Hex *varhex = [[Hex new] ctorString:[sym second]];
	Hex *vargulf = [[Hex new] ctorInt:atoi([[val second] UTF8String])];

	//NSLOG4(@"vars = %d %d val=%@",[varhex number],[vargulf number],[val second]);

	Symbol* s2 = [_symboltable searchForHex: varhex ];
	int address;
	if (s2 == nil) 
		address = -1;
	else
		address = [[s2 address] number];
	Symbol *s;
	//generate a new Hex _address, if _symboltable does not contain hexnumber address
	if (address < 0) {//var does not already exist 
		NSLOG(@"setfqAtom : no address found");
		address = [_machine generateFreeAddress];
		NSLOG2(@"TYPE=%d",[self getTypeOfString:[val second]]);
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ctype];
			break;
		case (const TYPE)itype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:itype];
			break;
		case (const TYPE)stype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:stype];
			break;
		case (const TYPE)ftype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			
			break;
		}
		NSLOG2(@"s addr= %d",[[s address] number]);
		[_symboltable addObject:s];

	} else {
		NSLOG(@"setfqAtom : address found");
		NSLOG2(@"+++++++++++++++>%d",[self getTypeOfString:[val second]]);
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ctype];
			[_machine pushDefinition:varhex with:[[Hex alloc]ctorInt:atoi([[val second] UTF8String])]];
			break;
		case (const TYPE)itype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:itype];
			[_machine pushDefinition:varhex with:vargulf];
			break;
		case (const TYPE)stype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:stype];
			[_machine pushDefinition:varhex with:vargulf];
			break;
		case (const TYPE)ftype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ftype];
			[_machine pushDefinition:varhex with:vargulf];
			break;
		case (const TYPE)symtype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			[_machine pushDefinition:varhex with:vargulf];
			break;
		//default type is symtype
		default:
		case -1:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			[_machine pushDefinition:varhex with:vargulf];
			break;
		}
	}
	[self setLastSymbol:s];
	//add symbol

	return 0;

}

//Form in [val second] gets assigned to variable
- (int) parseDefinitionOfsetfqWithForm:(TupleInt*)sym and:(TupleInt*)val
{
	//TODO optional documentation string
	Hex *varhex = [[Hex new] ctorString:[sym second]];

	NSLOG3(@"setfq vars = %d val=%@",[varhex number],[val second]);

	Symbol *s2 = [_symboltable searchForHex: varhex ];
	int address;
	if (s2 == nil)
		address = -1;
	else
		[[s2 address] number];
	Symbol *s;
	//generate a new Hex _address, if _symboltable does not contain hexnumber address
	if (address < 0) {//var does not already exist 
		NSLOG(@"setfq Form : no address found");
		address = [_machine generateFreeAddress];
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ctype];
			break;
		case (const TYPE)itype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:itype];
			break;
		case (const TYPE)stype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:stype];
			break;
		case (const TYPE)ftype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			s = [[Symbol new] ctorName:[sym second] form:[[Form alloc] initWithString: [val second]] type:symtype];
			
			break;
		}
		[_symboltable addObject:s];
	} else {
		switch ((TYPE)[self getTypeOfString:[val second]]){
		case (const TYPE)ctype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ctype];
			break;
		case (const TYPE)itype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:itype];
			break;
		case (const TYPE)stype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:stype];
			break;
		case (const TYPE)ftype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:ftype];
			break;
		case (const TYPE)symtype:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		//default type is symtype
		default:
		case -1:
			[_symboltable addObjectExists:varhex form:[[Form alloc] initWithString:[val second]] type:symtype];
			break;
		}

	}
	[self setLastSymbol:s];
	return 0;
}

- (int) parseAssignment:(TupleInt*)status withValue:(TupleInt*)value
{

	[_symboltable set:[status second] value:[value second]];
	[_machine pushAssignment:[[Hex new] setNumber:[status second]] with:[[Hex new] setNumber:[value second]]];//FIXME value NSString etc to number	
	return 0;
}


- (int) setLastSymbol:(Symbol*)s
{

	_lastsymbol = s;
	return 0;

}

- (NSMutableArray*)splitForms:(NSString*)formstring
{
	//NOTE reversed formstring !
	NSMutableArray *array = [[NSMutableArray alloc] init];
	int idx = 0;
	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	char c;
	int nopen = 0;
	int nclosed = 0;
	while (idx < [formstring length]) {
		//NSLog(@"idx=%d c=%c",idx,[formstring characterAtIndex:idx]);
		//if ((c = [formstring characterAtIndex:idx]) == '`') {
			
		//} else 
		if ((c = [formstring characterAtIndex:idx]) == '(')
			nopen++;//NOTE formstring is reversed
			if (nopen == nclosed && nopen != 0 && nclosed != 0) {
				[s appendFormat:@"%c",c];
				Form *form = [[Form alloc] initWithString:s];
				//Form get formatted inherently with fomatLisp
				//in the above ctor
				NSLOG(@"Added form to array");
				[array addObject:form];
				s =[[NSMutableString alloc] initWithString: @""];
				nopen = nclosed = 0;
			}
		else if ((c = [formstring characterAtIndex:idx]) == ')') {
			nclosed++;//NOTE formstring is reversed
			[s appendFormat:@"%c",[formstring characterAtIndex:idx]];
		}
		else {
			[s appendFormat:@"%c",[formstring characterAtIndex:idx]];
		}
		idx++;
	 }

	//FIXME Lisp [fileName addStatus:HAVE_CLOSINGBRACE String:&st];
	NSLOG(@"Array of Forms done.");
	return array;

}
/*
- (int)hasSubForms:(NSString*)formstring
{
	NSMutableArray *array = [self splitForms:formstring];
	NSEnumerator *iter = [array objectEnumerator];
	Form *f;
	int n = -1;
	while (f = [iter nextObject])
		n++;
	if (n > -1)
		return n+2;//-1 and 0 
	else
		return -1;
}
*/
- (TupleInt*)hasSubForms:(NSString*)formstring
{
	NSMutableArray *array = [self splitForms:formstring];
	NSEnumerator *iter = [array objectEnumerator];
	Form *f;
	int n = -1;
	while (f = [iter nextObject]) {//TODO better implementation
		if ([formstring compare:[f string]] == 0)
			return [[TupleInt alloc] addFirst:-1 andSecond:nil];
		n++;
	}
	if (n > -1)
		//n+2, -1 and 0 
		return [[TupleInt alloc] addFirst:n+1 andSecond:array];
	else
		return [[TupleInt alloc] addFirst:-1 andSecond:nil];
}


- (int) parsePlus:(TupleInt*)ti
{					
	switch (((TYPE)[self getTypeOfString:[ti second]])) {
		
	case (const TYPE)ctype:{ //NOTE character (conversion from char to int - ascii)
		int a = atoi([[ti second] UTF8String]);
		NSString *s = [NSString stringWithFormat:@"%d",a];
		NSLOG2(@"converted ascii a=%@",s);
		[_machine pushOperatorPlusConstant:s];
		//TODO [self setLastSymbol:s2];
		return 0;
		break;
	}
	case (const TYPE)itype:{ //integer
		Hex* varhex = [[Hex alloc] ctorString:[ti second]];
		Symbol *s2 = [_symboltable searchForHex: varhex ];
		int address; 
		if (s2 == nil)
			address = -1;
		else
			address = [[s2 address] number];

		NSLOG2(@"address=%d",address);

		if (address > -1) //symbol exists
			[_machine pushOperatorPlusSymbol:[s2 address]];
		else				
			[_machine pushOperatorPlusConstant:[ti second]];
		[self setLastSymbol:s2];
		return 0;
		break;
	}
	case (const TYPE)ftype: //float
	//[_machine pushOperatorPlusConstant:[ti second]];//TODO foating point unit code
		break;
	case (const TYPE)symtype:
		default:{

			Hex* varhex = [[Hex alloc] ctorString:[ti second]];
			Symbol *s2 = [_symboltable searchForHex: varhex ];
			int address; 
			if (s2 == nil)
				address = -1;
			else
				address = [[s2 address] number];
			NSLOG2(@"address2=%d",address);
			if (address > -1) {//symbol exists
							
				[_machine pushOperatorPlusSymbol:[s2 address]];
				[self setLastSymbol:s2];
				return 0;
			} else {
				//symbol does not exist
				//thus can not be computed
				//TODO [self setLastSymbol:s2];
				NSLOG2(@"Invalid Types for + operator, TODO : no float type=%d", [self getTypeOfString:[ti second]]);
				//[form addError:
				return -1;
			}
			break;
		}
	}
	return -1;
}

- (int) parseMin:(TupleInt*)ti
{					
	switch (((TYPE)[self getTypeOfString:[ti second]])) {
		
	case (const TYPE)itype:{ //integer
		Hex* varhex = [[Hex alloc] ctorString:[ti second]];
		Symbol *s2 = [_symboltable searchForHex: varhex ];
		int address; 
		if (s2 == nil)
			address = -1;
		else
			address = [[s2 address] number];

		NSLOG2(@"address=%d",address);

		if (address > -1) //symbol exists
			[_machine pushOperatorMinusSymbol:[s2 address]];
		else				
			[_machine pushOperatorMinusConstant:[ti second]];
		return 0;
		break;
	}
	case (const TYPE)ftype: //float
	//[_machine pushOperatorMinusConstant:[ti second]];//TODO foating point unit code
		break;
	case (const TYPE)symtype:
		default:{
			Hex* varhex = [[Hex alloc] ctorString:[ti second]];
			Symbol *s2 = [_symboltable searchForHex: varhex ];
			int address;
			if (s2 == nil) 
				address = -1;
			else
				address = [[s2 address] number];
			if (address > -1) {//symbol exists
							
				[_machine pushOperatorMinusSymbol:[s2 address]];
				return 0;
			} else {
				//symbol does not exist
				//thus can not be computed
				NSLOG(@"Invalid Types for - operator, TODO : no float");
				//[form addError:
				return -1;
			}
			break;
		}
	}
	return -1;
}

- (int) parseMul:(TupleInt*)ti
{					
	switch (((TYPE)[self getTypeOfString:[ti second]])) {
		
	case (const TYPE)itype:{ //integer
		Hex* varhex = [[Hex alloc] ctorString:[ti second]];
		Symbol *s2 = [_symboltable searchForHex: varhex ];
		int address; 
		if (s2 == nil)
			address = -1;
		else
			address = [[s2 address] number];

		NSLOG2(@"address=%d",address);

		if (address > -1) //symbol exists
			[_machine pushOperatorMulSymbol:[s2 address]];
		else				
			[_machine pushOperatorMulConstant:[ti second]];
		return 0;
		break;
	}
	case (const TYPE)ftype: //float
	//[_machine pushOperatorMulConstant:[ti second]];//TODO foating point unit code
		break;
	case (const TYPE)symtype:
		default:{
			Hex* varhex = [[Hex alloc] ctorString:[ti second]];
			Symbol *s2 = [_symboltable searchForHex: varhex ];
			int address;
			if (s2 == nil) 
				address = -1;
			else
				address = [[s2 address] number];
			if (address > -1) {//symbol exists
							
				[_machine pushOperatorMulSymbol:[s2 address]];
			} else {
				//symbol does not exist
				//thus can not be computed
				NSLOG(@"Invalid Types for * operator, TODO : no float");
				//[form addError:
				return -1;
			}
			return 0;
			break;
		}
	}
	return -1;
}

-(int) skipWordAndWhiteSpace:(Form*)form withIndex:(int)idx
{
	//skip "first word"
	TupleInt *ti = [self grepWordOfLineParens:[form string] withIndex:idx];
	//skip prevailing whitespace
	NSLOG2(@"skip = %@",[ti second]);
	TupleInt *ti2 = [self skipWhiteSpace:[form string] withIndex:[ti first]];
	return [ti2 first];
}

-(int) skipFormAndWhiteSpace:(Form*)form withIndex:(int)idx
{
	int nopen = 0, nclosed = 0;
	int pidx = idx;

	if (idx > [form string])
		return -1;

	while (idx < [[form string] length]) {
		char c = [[form string] characterAtIndex:idx];
		if (c == '(')
			nopen ++;
		if (c == ')') {
			nclosed ++;
	
			if (nclosed == nopen && nopen > 0) {
				idx++;
				TupleInt *ti = [self skipWhiteSpace:[form string] withIndex:idx];
				return [ti first];
			}
		}
		//skip prevailing whitespace
		NSLOG2(@"skipForm = %c",c);
		idx++;
	}
	return idx;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ArmLispScanner.h"

@implementation ArmLispScanner

- (ArmLispScanner*)ctor {

}

/**********
*- (int)scanFile:(FileName*)fileName withCompiler:(Compiler*)compiler {
*	
*	//init fileBuffer
*	[fileName scan];
*	[compiler scanFile:fileName];
*	
*	return 0;
*}
***********/
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ArmScanner.h"

@implementation ArmScanner

- (int)scanFile:(FNString*)fileName withCompiler:(Compiler*)compiler {
	
	//init fileBuffer
	[fileName scan];
	[compiler scanFile:fileName];
	
	return 0;
}
/*
-(int)subCompile:(FNString*)fileName withCompiler:(Compiler*)compiler {
	[fileName readInFile];//FIXME fileName scan 
	[compiler scanFile
 */
@end/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import "ArmSubCompiler.h"
#include <unistd.h>
#include <stdlib.h>

@implementation ArmSubCompiler

- (ArmSubCompiler*)ctor:(NSString*)command {
	
	_compilerShellCommand = command;
	
	return self;

}

-(int)errorset  {

	return  ([_errorsubcompiler errorset]);

}

- (void)compile:(FNString*)fileName {
	//override for other sub compiler
	if ([fileName isCSource] 
		|| 
		[fileName isCHeader]) {
		_compilerShellCommand = @"arm-eabi-gcc";//FIXMENOTETODO
	}
	_armSubScanner = [ ArmSubScanner new ];
	[ _armSubScanner scanFile:fileName withCompiler: self ];
	
	return;
}

- (void) scanFile:(FNString*)fileName {
	
	[self scanFileRec:fileName];
	
}

- (int)scanFileRec:(FNString*)fileName {
	int status = -1;
	int error = -1;
	//scan for pure C code
	if (error = [self subCompilable:fileName]) {
		if (error == 0) {
			status = PURECCOMPILE;
			[fileName addStatus:status];
		} else {
			[fileName addError:error];
		}
	} else if (error = [self subCompilableObjCSourceFile:fileName]) {
		if (error == 0) {
			status = OBJCHEADERCOMPILE;
			[fileName addStatus:status];
		} else {
			[fileName addError:error];
		}
	}
	
	return status;
	
}

- (int)subCompilable:(FNString *)fileName {
	//scan for pure C code
	FILE * fp;
	
	if ((fp = popen((const char *)[NSString stringWithFormat:@"%@/%@/%@", _compilerShellCommand, " -c ", fileName], "r+")) == (FILE *)0) {
		[fileName addError:SUBCOMPILENOT];
		return -1;
	}
	
	FILE *fp2;
	if ((fp2 = fopen((char *)fileName, "w")) < 0) {
		[fileName addError:SUBCOMPILENOT];
		return -1;
	}
	//FIXME flock
	
	int i = -1;
	NSString*s;
	char c;
	while (read(fileno(fp),&c,1) != EOF) {
		if (s == @"error") {
			return -1;//file is not pure C
		} else if (c == ' '
				   ||
				   c == '\t'
				   ||
				   c == '\n') {
			s = @"";
			continue;
		} else {		
			s += [[fileName bufferstring] characterAtIndex:i];
			write(fileno(fp2), &c, 1);
		}
	}
	
	return 0;//file is pure C
}

- (int) subCompilableObjCSourceFile:(FNString*)fileName {
	int idx = -1;
	
	int len = [[fileName buffer] length];
	
	for ( idx = 0; idx < len; idx++ ) {
		idx = [self subCompilableRec:(FNString*)fileName withIndex:idx];
		//and again search for another objC function definition	

		if ([self errorset]) {
			[fileName addErrors:_errorsubcompiler];
			[_errorsubcompiler clear];
		}
	}
	
	return 0;//FIXME
}

- (int)subCompilableRec:(FNString*)fnstr withIndex:(int)idx{
	//compile pure C code in function definitions to ObjC source file which is compiled by compileRec method
	int i = idx;
	
	NSString *pstr = [fnstr bufferstring];
	int fno;
	if ((fno = mkstemp("/tmp/bovisbuves.c")) < 0) {
		[self erroradd: SUBCOMPILENOMKSTEMP];
		idx = i;
		return idx;//SUBCOMPILENOMKSTEMP;
	}
	
    if (flock(fno, LOCK_SH) < 0) {
		idx = i;
		return idx;//SUBCOMPILECANNOTLOCK;
	}
	
	NSString*is;
	int j = i;
	
lable1:
	
	while (++i && ([[pstr buffer] characterAtIndex:i] != '#')) {
		
		if (i >= [[pstr buffer] length]) {
			i = j;
			goto lable2;
		}
		
		is += [[pstr buffer] characterAtIndex:i];
		if (is == @"#include") {
			while (++i && ([[pstr buffer] characterAtIndex:i] != '<' || [[pstr buffer] characterAtIndex:i] != '"')) {
				is += [pstr characterAtIndex:i];
				if ([[pstr buffer] characterAtIndex:i] == '>' || [[pstr buffer] characterAtIndex:i] == '"') {//e.g. #include <stdarg.h"
					write(fno, (char *)is, [is length]);
					pid_t pid1;
					if ((pid1 = fork()) < 0) {
						idx = i;
						return idx;//SUBCOMPILECANNOTFORK;
					} else if (pid1 == 0) {
						is = @"";
						goto lable1;
					} else {
						goto lable2;
					}
				}
			}
		}
	}
	
lable2:
	
	i = j;
	
	while (++i && [[pstr buffer] characterAtIndex:i] != '-')//--FIXME - minus in C code && nested ((())) 
		;
	//function header (of definition
	idx = i;
	int declstatus = [self scanObjCMethodDeclarationIn:pstr withIndex:idx fino:fno];
	
	//faulty declaration ?
	if (declstatus < 0) {
		idx = i;
		return idx;//SUBCOMPILENOT;
	}

	//block start
	write(fno,"{",1);
	write(fno,"\n",1);
	
	//FIXME following code compiles the following method
	while (++i && ([[pstr buffer] characterAtIndex:i] != '{'))
		;

		
	while (++i && [[pstr buffer] characterAtIndex:i] != '}')
		if (i+1 >= [[pstr buffer] length]) {
			close(fno);
			idx = i;
			return idx;//SUBCOMPILENOT;
		} else {
			NSString*s;
			s += [pstr characterAtIndex:i];
			write(fno, [NSString stringWithFormat:@"%@", [pstr characterAtIndex:i]],1);
		}
	
	
	FILE *fp;
	//FIXME -I./PWD/
	if ((fp = popen((const char *)[NSString stringWithFormat:@"%@/%@", _compilerShellCommand, " -c /tmp/bovisbuves.c"], "r+")) == (FILE *)0) {
		idx = i;
		return idx;//SUBCOMPILENOT;
	}
	if (flock(fileno(fp), LOCK_SH) < 0) {
		idx = i;
		return idx;//SUBCOMPILECANNOTUNLOCK;
	}
	//try to subcompile
	FNString*subFileName = [FNString new];
	subFileName = (FNString*)@"/tmp/bovisbuves.c";
	[subFileName readInFile];
	[self subCompilable:subFileName];
	
	//close function block
	write(fno, "}", 1);

	if (flock(fileno(fp), LOCK_UN) < 0) {	
		idx = i;
		return idx;//SUBCOMPILECANNOTUNLOCK;
	}
	if (flock(fno, LOCK_UN) < 0) {
		idx = i;
		return idx;//SUBCOMPILECANNOTUNLOCK;
	}
	
	fclose(fp);

	idx = i;
	return idx;
}

//FIXME for source files -> compilable method
- (int) scanObjCMethodDeclarationIn:(FNString*)fileName withIndex:(int)idx fino:(int)fno{
	struct RType* returnType;
	NSString*funcName;
	NSMutableArray*Args;
	
	int oldidx = idx;
	
	while(++idx < [[fileName buffer] length]) {
		if ([[fileName buffer] characterAtIndex:idx] == '(') {
			returnType = NULL;
			
			idx = [self scanDeclarationForType:[fileName buffer] withIndex:idx returns:returnType];
			if ([self errorset]) {
				[_errorsubcompiler addError:SUBCOMPILEINVALIDRETURNTYPE];
				idx = oldidx; 
				continue;
				////return SUBCOMPILEINVALIDRETURNTYPE;
			}
			idx = [self scanDeclarationForFuncName:[fileName buffer] withIndex:idx returns:funcName];
			if ([self errorset]) {
				[_errorsubcompiler addError:SUBCOMPILEINVALIDFUNCNAME];
				idx = oldidx;
				continue;
				////return SUBCOMPILEINVALIDFUNCNAME;
			}
			idx = [self scanDeclarationForArgs:[fileName buffer] withIndex:idx returns:Args]; 
			if ([self errorset]) {
				[_errorsubcompiler addError:SUBCOMPILEINVALIDARGS];
				idx = oldidx; 
				continue;
				////return SUBCOMPILEINVALIDARGS;
			}
			
			if (oldidx == idx)
				[_errorsubcompiler addError:SUBCOMPILEINVALIDFUNCDEF];
				return idx;//SUBCOMPILEINVALIDFUNCDEF;
		}
	}
	
	[self writeDeclarationWithReturnTypeToHeader:returnType withFuncName:funcName andArgs:Args onfno:fno];
	
	return idx;
	
}

- (int) writeDeclarationWithReturnTypeToHeader:(struct RType*)returnType withFuncName:(NSString*)funcName andArgs:(NSMutableArray*)Args onfno:(int)fno {

	write(fno, (char *)returnType->rtypestring, strlen((char *)returnType->rtypestring));
	write(fno, " ", 1);
	write(fno, (char *)funcName, strlen((char *)funcName));
	write(fno, "(", 1);
	int j = -1;
	while (++j < [Args count]-1) {
		write(fno, (char *)[Args objectAtIndex:j], strlen((char *)[Args objectAtIndex:j]));
		write(fno, (char *)", ",2);
	}
	write(fno, (char *)[Args objectAtIndex:j], strlen((char *)[Args objectAtIndex:j]));
	write(fno, ")", 1);//FIXME ") {"
	
	return 0;

}

- (int) scanDeclarationForType:(NSString*)pstr withIndex:(int)idx returns:(struct RType*)rType{
	
	NSString*is;
	int subcount;
	while ([pstr characterAtIndex:idx] != ')' || subcount > 0) {
		
		if ([pstr characterAtIndex:idx] == '(') //scan for nested (((())) types e.g. function pointers
			subcount++;
		else if ([pstr characterAtIndex:idx] == ')') 
			subcount--;

		
		if (idx > [pstr length]) {
			rType = (struct RType*)malloc(sizeof(struct RType));
			rType->rtypestring = @"";
			rType->id = -1;
			return -1;
		}
		is += [pstr characterAtIndex:idx];
	}
	
	long r = random();
	long r2 = random();
	long r3 = r2;
	long result = 0;
	
	if ([_classLocator locateType:[[TypeName init] ctor:r withTypeName:is]] < 0) {
		rType = (struct RType*)malloc(sizeof(struct RType));
		rType->rtypestring = @"";
		
		//make number string for id
		for ( ;; ) {
			
			r3 = r2 % 2;
			r2 -= (r2 % 10);//base 10
			
			result += r3;
			
		}
		
		rType->id = result;
		//rType->id = r2 % INT_MAX;//--FIXME repeated ids
		return idx;//-1;
	}
		
	//skip whitespace
	for ( ;[pstr characterAtIndex:idx] == ' '
		   || 
		   [pstr characterAtIndex:idx] == '\t'
		   || 
		 [pstr characterAtIndex:idx] == '\n'; )
		idx++;
	
	rType = (struct RType*)malloc(sizeof(struct RType));
	rType->rtypestring = is;
	rType->id = r2 % INT_MAX;//--FIXME repeated ids
	
	return idx;//0;
	
}

		  
- (int) scanDeclarationForFuncName:(NSString*)pstr withIndex:(int)idx returns:(NSString*)rName{
	NSString*is;
	while ([pstr characterAtIndex:idx] != '(') {
				  
		if (idx > [pstr length]) {
			rName = @"";
			return idx;//-1;
		}
		is += [pstr characterAtIndex:idx];
	}
			  
			  
	rName = is;
	return 0;	  
}
		  

- (int) scanDeclarationForArgs:(NSString*)pstr withIndex:(int)idx returns:(NSMutableArray*)rArgs{
	
	NSMutableArray*lis;
	struct RType*is;
	while ([pstr characterAtIndex:idx] != '{') {
		
		while ([pstr characterAtIndex:idx] != '(') 
			;
		
		if (idx > [pstr length]) {
			rArgs = lis;
			return idx;//0;
		}
		if ([self scanDeclarationForType:pstr withIndex:idx returns:is] < 0) {
			rArgs = lis;
			return idx;//-1;
		}
		else {
			//scan for argname
			NSString*argname;
			while ((idx) < [pstr length]) {
				if ([pstr characterAtIndex:idx] != ' ' || [pstr characterAtIndex:idx] != ')') {
					argname += [pstr characterAtIndex:idx];
				} else {
					is->rtypestring = [NSString stringWithFormat:@"%@/%@",is,argname];
					break;
				}
				idx++;
			}
		}	
		
		is += [pstr characterAtIndex:idx];
		
		//skip whitespace
		while ([pstr characterAtIndex:idx] == ' ' 
			   || 
			   [pstr characterAtIndex:idx] == '\t' 
			   || 
			   [pstr characterAtIndex:idx] == '\n')
			idx++;
		
		//FIXME rtypestring
		if ([_classLocator locateType:[[TypeName init] ctor:-1 withTypeName:is->rtypestring]] < 0) {
			[lis addObject:is->rtypestring];//--FIXME rtypestring
		}
	}
	
	return idx;//0;
}

- (int)compilablesource:(FNString*)fileName {
	//subcompile(rec)
	int status = [self subCompilable:fileName];
	if (status < 0) {
		//compile pure C code in function definitions (FIXME)
		return [self subCompilableObjCSourceFile:fileName];
	} else {
		return status;
	}
}


//compile objC code in file fileName
- (int)compileRec:(FNString*)fileName {

	if ([fileName readInFile] < 0)
		return -1;
	
	
	NSString *fileContents = [fileName stringFromIndex:0 toIndex:[[fileName buffer] length]];
							  
	int i = -1;
							  
	if (i < [fileContents length]) {
		while (++i && [fileContents characterAtIndex:i] != '-')//--FIXME - minus in C code && nested ((())) 
			;
		
		//FIXME flock
		FILE *fp = fopen("/tmp/bovisbuvesXXX", "w+");
		int fno = fileno(fp);
		//function header (of definition
		int i = [self scanObjCMethodDeclarationIn:fileName withIndex:i fino:fno];
							  
		//faulty declaration ?
		if ([self errorset]) {//never reached
			return SUBCOMPILENOT;
		}
	
		while (++i && [fileContents characterAtIndex:i] != '{')//--FIXME - minus in C code && nested ((())) 
			;
		
		i = [self compileObjC:i];
	}
	
	return i;
							  
}

- (int)compileObjC:(int)idx {
	return 0;					  
}
							  
- (void)erroradd:(int)ei {

	[_errorsubcompiler addError: ei];	

}


@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ArmSubScanner.h"


@implementation ArmSubScanner

- (int)scanFile:(FNString*)filename withCompiler:(Compiler*)compiler {

	
	return 0;
}


@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ByteCodeMachine.h"

@implementation ByteCodeMachine

- (int) type
{
	return _type;
}

- (int)pushDefinition:(Hex*)hex {return -1;}
- (int)pushAssignment:(Hex*)hex {return -1;}
- (int)pushOperatorPlus:(Hex*)addr { return 1; }
- (int)pushOperatorPlusConstant:(NSString*)addr { return 1; }
- (int)pushOperatorPlusSymbol:(Hex*)hex { return -1; }
- (int)pushOperatorMinusConstant:(NSString*)addr { return 1; }
- (int)pushOperatorMinusSymbol:(Hex*)hex { return -1; }
- (int)pushOperatorPlusPlus:(Hex*)addr { return -1; }
- (int)pushOperatorPlusAssign:(Hex*)addr { return -1; }
- (int)pushOperatorMinus:(Hex*)addr { return -1; }
- (int)pushOperatorMinusMinus:(Hex*)addr { return -1; }
- (int)pushOperatorMinusAssign:(Hex*)addr { return -1; }
- (int)pushOperatorOr:(Hex*)addr { return -1; }
- (int)pushOperatorBitwiseOr:(Hex*)addr { return -1; }
- (int)pushOperatorExclusiveOr:(Hex*)addr { return -1; }
- (int)pushOperatorBitwiseExclusiveOr:(Hex*)addr { return -1; }
- (int)pushWhile:(Hex*)addr { return -1; }
- (int)pushLoopDefaultRegister { return -1; }
- (int)pushLoopGoto:(NSString*)l { return -1; }
- (int)pushIf:(Hex*)addr { return -1; }
- (int)pushLoadSymbol:(Hex*)hex { return -1; }
- (int)pushLoadConstant:(Hex*)hex { return -1; }
- (int)pushIfConstant:(int)addr { return -1; }
- (int)pushIfDefaultRegister { return -1; }
- (int)pushElse:(Hex*)addr { return -1; }
- (int)pushPreviousLabel { return -1; }
- (int)pushNewLabel { return -1; }
- (int)pushNewLabel:(NSString*)l { return -1; }
- (int)getLastLabel { return -1; }
- (int)generateFreeAddress {_freeaddycounter += 256*4; return _freeaddycounter;}
- (NSString*)generateFreeLabel {_freelabelcounter += 4; 
				NSMutableString *rs = [[NSMutableString alloc] initWithString:@"label"];
				[rs appendFormat: @"%d:",_freelabelcounter];
				return rs; }
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import "ClassLocator.h"
#import "TypeName.h"

@implementation ClassLocator

- (int) isa: (TypeName*)typename in: (GBAObject *)gbao {
	
	return [gbao isa:typename];
	
}

- (int) locateType:(TypeName*)type {
	
	if ([self isNativeType:type])
		return 0;
	if ([self isClassType:type])
		return 1;

	return -1;
}

- (int) isNativeType:(TypeName*)t {
	if ([t string] == @"void" || [t string] == @"int" || [t string] == @"char") {
		return 0;
	}
	else 
		return -1;
}

- (int) isClassType:(TypeName*)t {
	//FIXME locate class type in class Database
	return -1;
}


@end
/*
Copyright (C) Johan Ceuppens 2012
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#import "Compiler.h"


@implementation Compiler

- (void)compile:(FNString*)fileName {
	
}
/*
- (void)scan {
	
}
*/
- (void) scanFile:(FNString*)fileName {
	
}

- (int) scanFileRec:(FNString*)fileName {
	return -1;
}

- (int)compilable:(FNString*)fileName {
	return -1;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "DataArray.h"


@implementation DataArray

- (DataArray *)ctor {
	[_datas ctor:256*256];//--FIXME fixed size
	return self;
}

//seek typename's id returns 0 if found, -1 if not found, rString contains typename matched by id
- (int) matchDataId:(int)tni returns:(void*)rString {
	[_datas matchWithKey: tni returns:rString];
	
	if (rString > 0)
		return 0;
	else {
		memset((void *)rString, 0, sizeof(rString));
		return -1;
	}

}

//seek data returns 0 if found -1 if not found
- (int) matchData:(Data *)tn {
	void* rString;
	//FIXME [self matchDataId:[tn type] returns: rString];
	
	if (rString > 0)
		return 0;
	else {
		memset((void *)rString, 0, sizeof(rString));
		return -1;
	}
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Data.h"

@implementation Data 

- (int) setData:(void *)data {
	memcpy(_data->data, data, sizeof(*data));
	_data->datalength = sizeof(*data);

	type = 0;//FIXME 
}

- (void*)data {
	return _data;
}

- (int)type {
	return type;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Dispatcher.h"



@implementation Dispatcher

- (void) addNode:(GBAObject*)node {

	//[node isa

}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "Error.h"
#import "TupleInt.h"

@implementation Error

-(void) addError:(int)ei {
	
	switch (ei) {
		case 0:{
			break;
		}
		case UNKNOWNFILEFORMAT:{
			[_errorstrs addObject:[[TupleInt alloc] addFirstInt:ei andSecond: @"Unknown File Format. Not .m or .h"]];
			break;
		}
		default:{
		}
	}
	
}

-(void)addErrorTuple:(Tuple*)t {
	[_errorstrs addObject:t];
}

//is there an error in the str db ?
- (int)errorset {

	return [_errorstrs count];
}

-(void)clear {
	[ _errorstrs removeAllObjects];
}

-(NSMutableArray*)getErrors {
	return _errorstrs;
}
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "ErrorSubCompiler.h"


@implementation ErrorSubCompiler

-(void) addError:(int)ei {
	
	switch (ei) {
		case SUBCOMPILENOT:{
			[_errorstrs addObject:[[ Tuple new] addFirst:ei andSecond: @"Cannot compile"]];
			break;
		}
		case SUBCOMPILEINVALIDRETURNTYPE:{
			[_errorstrs addObject:[[ Tuple new] addFirst:ei andSecond: @"Invalid return type"]];
			break;
		}
		case SUBCOMPILEINVALIDFUNCNAME:{
			[_errorstrs addObject:[[ Tuple new] addFirst:ei andSecond: @"Invalid function name"]];
			break;
		}
		case SUBCOMPILEINVALIDARGS:{
			[_errorstrs addObject:[[ Tuple new] addFirst:ei andSecond: @"Invalid function arguments"]];
			break;
		}
		case SUBCOMPILEINVALIDFUNCDEF:{
			[_errorstrs addObject:[[ Tuple new] addFirst:ei andSecond: @"Invalid function definition"]];
			break;
		}
		default:{
			[_errorstrs addObject:[[ Tuple new] addFirst:ei andSecond: @"Compiler error"]];
		}
	}
	
}

- (int)errorset {
	return [_errorstrs length];
}
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import "FileBuffer.h"


@implementation FileBuffer

- (FileBuffer*)ctor:(NSString*)s
{
	_string = [[NSString alloc] initWithString:s];
	return self;
}

- (NSString*)stringFromIndex:(int)start toIndex:(int)end {
	NSString *str = @"";
	int i = start;
	
	while (i < end) {
		str += [_string characterAtIndex:i++];
	}	
	
	return str;
	
}

- (NSString*)string
{
	return _string;
}

- (int)length
{
	return [_string length];
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "FileName.h"

@implementation OBJCARMFileName

- (OBJCARMFileName*)ctor {
	self = [super init];
	
	_errorobj = [Error new];
	
	if (self)
		return self;
	else 
		return (OBJCARMFileName*)0;

}

- (FileBuffer*)buffer {
	return _fileBuffer;
}

- (int) scan {
	
	if (_fileBuffer == (FileBuffer *)0)
		[_fileBuffer init];
	
	//FIXME put int thread
	//FIXME2 ecl
	[self readInFile];
	[self scancompile];
	
	//fprintf(stdout, "%c", [fileBuffer characterAtIndex: 0]);
	
	
	return 0;
}


- (int) readInFile {
	
	_fileBuffer = [FileBuffer new];
	FILE *fp;
	
	if ((fp = fopen([self UTF8String], "r")) == (FILE *)0) {
		fprintf(stderr, "- file scanner : cannot read in file."); 
		return -1;
	}
	
	if (flock(fileno(fp), LOCK_SH) < 0) {
		fprintf(stderr, "- file scanner : cannot lock shared lock.");
		return -1;
	}

	//code block
	fseek(fp, 0L, SEEK_END);
	long pos = ftell(fp);
	
	//read in file le
	unichar c;
	while (fseek(fp, pos--,SEEK_END) && pos >= 0 && (c = fgetc(fp)))
		_fileBuffer = (FileBuffer *)[_fileBuffer stringByAppendingString: [NSString stringWithCharacters:&c length: 1]]; 
	
	if (flock(fileno(fp), LOCK_UN) < 0) {
		fprintf(stderr, "- file scanner cannot unlock shared lock.");
		return -1;
	}
	if (!fclose(fp))
		return 0;
	else {
		fprintf(stdout, "- file scanner : cannot close readin file."); 
		return -1;
	}

}

- (int) scancompile{

	//FIXME err struct
	if (_fileBuffer == (FileBuffer *)0)
		return -1;
	
	//compiler = [ Compiler new ]; 
	//[scancompiler compile: _fileBuffer ]; 
	
	return 0;
	
}

- (int) isheader {
	
	if ([self length] < 2)
		return -1;
	
	if ([self characterAtIndex: ([self length]-1)] == 'h' 
		&&
		[self characterAtIndex: ([self length]-2)] == '.')
		return 0;
	
	return -1;
}

- (int) issource {
	
	if ([self length] < 2)
		return -1;
	
	if ([self characterAtIndex: ([self length]-1)] == 'm'
		&&
		[self characterAtIndex: ([self length]-2)] == '.')
		return 0;
	
	return -1;
}

- (int) isCHeader {
	
	if ([self length] < 2)
		return -1;
	
	if ([self characterAtIndex: ([self length]-1)] == 'h' 
		&&
		[self characterAtIndex: ([self length]-2)] == '.')
		return 0;
	
	return -1;
}

- (int) isCSource {
	
	if ([self length] < 2)
		return -1;
	
	if (//([self characterAtIndex: ([self length]-1)] == 'cc' 
		 /*||*/ [self characterAtIndex:([self length]-1)] == 'c'
		 //|| [self characterAtIndex:([self length]-1)] == 'cpp'
		
		&&
		[self characterAtIndex: ([self length]-2)] == '.')
		return 0;
	
	return -1;
}


- (void) addStatus:(int)s {
	
	[_statusobj addStatus:s ];

}

- (void) addError:(int)e {
	
	[_errorobj addError:e ];
	
}

- (NSString*)stringFromIndex:(int)start toIndex:(int)end {
	int i = start-1;
	NSString *str = @"";
	while (i < end) {
		str += [self characterAtIndex:i++];
	}
	
	return str;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "FileStream.h"

@implementation FileNameStream

- (FileNameStream*)ctor {
	
	return self;

}


- (int) open:(NSString*)filename {
	
	if ((_fp = fopen(filename, "rw")) == (FILE *)0) {
		fprintf(stderr, "- filenamestream : cannot read in file."); 
		return -1;
	}
	
	if (flock(fileno(_fp), LOCK_SH) < 0) {
		fprintf(stderr, "- filenamestream : cannot lock shared lock.");
		return -1;
	}

}

- (char)get {

	return (getc(_fp));

}

- (char)get:(int)index {

	//code block
	fseek(_fp, index, SEEK_SET);
	return (getc(_fp));

}	

- (int)close {
	
	if (flock(fileno(_fp), LOCK_UN) < 0) {
		fprintf(stderr, "- filenamestream cannot unlock shared lock.");
		return -1;
	}
	if (!fclose(_fp))
		return 0;
	else {
		fprintf(stdout, "- filestreamstream : cannot close readin file."); 
		return -1;
	}

}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "FNString.h"
#import "TupleIterator.h"

@implementation FNString

- (FNString*)ctor:(NSString*)filename {
	_filename = filename;
	_filebuffer = nil;//[[FileBuffer alloc] ctor:@""];
	_errorobj = [Error new];
	_statusobj = [Status new];
			
	return self;
}

- (FileBuffer*)buffer {
	if (_filebuffer != nil)
		return _filebuffer;
	return nil;
}

- (NSString*)bufferstring {
	if (_filebuffer != nil)
		return [_filebuffer string];
	return nil;
}

- (int) scan {
	
//	if (_filebuffer == (FileBuffer *)0)
//		[_filebuffer init];
	
	//FIXME put int thread
	//FIXME2 ecl
	[self readInFile];
	[self scancompile];
	
	//fprintf(stdout, "%c", [fileBuffer characterAtIndex: 0]);
	
	
	return 0;
}


- (int) readInFile {
	
	FILE *fp;
	NSLOG(@"reading in file...");	
	if ((fp = fopen([_filename UTF8String], "r")) == (FILE *)0) {
		fprintf(stderr, "- file scanner : cannot read in file."); 
		return -1;
	}
	
	if (flock(fileno(fp), LOCK_SH) < 0) {
		fprintf(stderr, "- file scanner : cannot lock shared lock.");
		return -1;
	}

	//code block
	fseek(fp, 0L, SEEK_END);
	long max = ftell(fp);
	long pos = 0;//ftell(fp);
	fseek(fp, max, SEEK_SET);
	pos = ftell(fp);
	pos-=2;
	//read in file le
	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	//unichar c;
	char c;
	//pos--;
	//while (fseek(fp, pos--,SEEK_END) && pos >= 0 && (c = fgetc(fp))) {
	while (fseek(fp, pos,SEEK_SET) == 0 && pos >= 0  && (c = getc(fp))) {

		//_filebuffer = (FileBuffer *)[_filebuffer stringByAppendingString: [NSString stringWithCharacters:&c length: 1]];
		[s appendFormat:@"%c",c];
		//printf("c=%c pos=%d\n",c,pos);
		//printf("s=%s\n",(char*)([s UTF8String]));
		//NSLog(@"c++");
		pos--;	
	}
	if (flock(fileno(fp), LOCK_UN) < 0) {
		fprintf(stderr, "- file scanner cannot unlock shared lock.");
		return -1;
	}
	if (!fclose(fp)) {
		NSString *st;
		//st = [NSString stringWithFormat:@"reading file done : %@", s];
		//NSLog(st);
		_filebuffer = [[FileBuffer alloc] ctor:s];	
		return 0;
	} else {
		fprintf(stdout, "- file scanner : cannot close readin file."); 
		return -1;
	}
	return -1;
}

- (int) scancompile{

	//FIXME err struct
	if (_filebuffer == (FileBuffer *)0)
		return -1;
	
	//compiler = [ Compiler new ]; 
	//[scancompiler compile: _filebuffer ]; 
	
	return 0;
	
}

- (int) isheader {
	
	if ([self length] < 2)
		return -1;
	
	if ([self characterAtIndex: ([self length]-1)] == 'h' 
		&&
		[self characterAtIndex: ([self length]-2)] == '.')
		return 0;
	
	return -1;
}

- (int) issource {
	
	if ([self length] < 2)
		return -1;
	
	if ([self characterAtIndex: ([self length]-1)] == 'm'
		&&
		[self characterAtIndex: ([self length]-2)] == '.')
		return 0;
	
	return -1;
}

- (int) isCHeader {
	
	if ([self length] < 2)
		return -1;
	
	if ([self characterAtIndex: ([self length]-1)] == 'h' 
		&&
		[self characterAtIndex: ([self length]-2)] == '.')
		return 0;
	
	return -1;
}

- (int) isCSource {
	
	if ([self length] < 2)
		return -1;
	
	if (//([self characterAtIndex: ([self length]-1)] == 'cc' 
		 /*||*/ [self characterAtIndex:([self length]-1)] == 'c'
		 //|| [self characterAtIndex:([self length]-1)] == 'cpp'
		
		&&
		[self characterAtIndex: ([self length]-2)] == '.')
		return 0;
	
	return -1;
}


- (void) addStatus:(int)s {
	
	[_statusobj addStatus:s ];

}

- (void) addStatusFirst:(int)status andSecond:(NSObject*)oi 
{
	[_statusobj addStatus:status withObject:oi ];
}

- (void)addStatus:(int)status String:(NSString**)s
{
	[_statusobj addStatusFirst:status andSecond:*s];
}

- (void)printStatus:(int)status
{

	Tuple *t = [_statusobj getObject:status];	
	TupleIterator *ti = [TupleIterator ctor:t];

	while (![ti atEnd]) {
		printf("%s", [[t second] UTF8String]);
		t = [ ti next ];		
	}

}

- (void) addError:(int)e {
	
	[_errorobj addError:e ];
	
}

- (NSString*)stringFromIndex:(int)start toIndex:(int)end {
	int i = start-1;
	NSString *str = [[NSString alloc] initWithString:@""];
	while (i < end) {
		str += [[self bufferstring] characterAtIndex:i++];
	}
	
	return str;
}

- (void)addErrors:(Error*)err {

	NSEnumerator *e = [[err getErrors] objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		[_errorobj addErrorTuple: object];
	}

}

- (Tuple*)getLastStatus
{

	Tuple *t = [_statusobj getObject:[_statusobj length]];	
	return t; 

}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "Form.h"
#import "TupleIterator.h"

@implementation Form

- (Form*)initWithString:(NSString*)fs
{
	_formstring = [[NSMutableString alloc] initWithString:@""];
	[_formstring appendFormat:@"%@",fs];
	//_formstring = fs;
	//printf("formstring = %s\n", [fs UTF8String]);
	if ([self formatLisp] < 0)
		return nil;

	return self;
}

- (NSString*)string
{
	return _formstring;
}
- (void)setString:(NSString*)s
{
	_formstring = s;
}

/*
 * Lisp Form Compilation methods
 */ 
/*- (int)compile:(ByteCodeMachine*)machine
{
	_machine.machine = machine;

	[self formatLisp];

	return 0;
}
*/
/*
 * Lisp Form Internal Compilation methods
 */

- (int)skipWhiteSpace:(NSString*)buffer atIndex:(int)idx
{
	while ([buffer characterAtIndex:idx] == ' ' ||
		[buffer characterAtIndex:idx] == '\t')
		idx++;

	return idx;
}

- (int)skipWhiteSpaceBackwards:(NSString*)buffer atIndex:(int)idx
{
	while ([buffer characterAtIndex:idx] == ' ' ||
		[buffer characterAtIndex:idx] == '\t')
		idx--;

	return idx;
}

// NOTE form is reversed string !
//TODO better catenation
- (int)formatLisp
{
	//do not format if there are no parenses
	if ([self isForm] < 0)
		return 0;

	if (_formstring == nil)
		return -1;

	if ([_formstring length] <= 0)
		return -1;

	NSMutableString *returnbuffer1 = [[NSMutableString alloc] initWithString:@""];
	NSMutableString *returnbuffer2 = [[NSMutableString alloc] initWithString:@""];
	int idx = [_formstring length]-1;
	while (idx >= 0) {//NOTE idx<0 gives truth for character index access in NSString _formstring	
		//NSString *st;
		//st = [NSString stringWithFormat:"st=%@",idx];
		//NSLog(st);
		if ([_formstring characterAtIndex:idx] == '(') {
			idx = [self skipWhiteSpaceBackwards:_formstring atIndex:idx];
		}
		[returnbuffer1 appendFormat:@"%c",[_formstring characterAtIndex:idx]];
		//returnbuffer1 += [_formstring characterAtIndex:idx];
		idx--;
	}
	idx = [returnbuffer1 length]-1;
	while (idx >= 0) {
		if ([returnbuffer1 characterAtIndex:idx] == ')') {
			idx = [self skipWhiteSpaceBackwards:returnbuffer1 atIndex:idx];
		}
		[returnbuffer2 appendFormat:@"%c",[returnbuffer1 characterAtIndex:idx]];
		//returnbuffer2 += [returnbuffer1 characterAtIndex:idx];
		idx--;
	}

	_formstring = returnbuffer2;
	return 0;
} 

- (void) addStatus:(int)s {
	
	[_statusobj addStatus:s ];

}

- (void) addError:(int)e {
	
	[_errorobj addError:e ];
	
}

- (void) reverse
{
	NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	[s appendFormat:@"%@",_formstring];
	NSMutableString *rets = [[NSMutableString alloc] initWithString:@""];
	int idx = [s length]-1;
	while (idx >= 0) {
		[rets appendFormat:@"%c",[s characterAtIndex:idx]];
		idx--;
	}

	_formstring = (NSString*)rets;
}

- (int)isForm
{
	//coolness : a word is short in length,
	// a form always has index:0 as a parens,
	//thus this returns after 1 loop :-)
	int i = 0;
	while (i < [_formstring length]) {//TODO maybe check for format
		if ([_formstring characterAtIndex:i] == '(')
			return 0;
		i++;
	}
	NSLOG2(@"LOOP=%d",i);
	return -1;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Fuzzy.h"
#include <assert.h>

@implementation Fuzzy

- (int)mulinit:(int*)_rv {
	[self mul:_vector and:(int**)_matrix returns:_rv];
	return 0;
}

- (int) mul:(int*)_v and:(int**)_m returns:(int*)_rv {
	int i,j;
	
	for (; i < sizeof(_v)/sizeof(int); i++) {
		for (; j < sizeof(_v)/sizeof(int); j++) {
			
			_rv[j] += _m[j][i]*_v[j];
			
		}
	}
	return 0;
}

- (double) fitnessForMax:(int)max {
	int i;
	double r;
	int *v;
	[self mulinit:v];
	for (; i < max; i++) {
		r += v[i];
	}
	
	r /= i;
	return r;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "GBAObject.h"


@implementation GBAObject

- (NSString *)string {
	return name;
}

- (int) isaid:(int)typenamei {
	NSString *morbo = nil;
	return [typenamearray matchTypeNameId:typenamei returns:morbo];
}

- (int) hasaid:(int)methodnamei {
	return [methodnamearray matchMethodNameId:methodnamei];
}

- (int) isa:(TypeName*)typename {
	return [typenamearray matchTypeName:typename];
}

- (int) hasa:(MethodName*)methodname {
	return [methodnamearray matchMethodName:methodname];
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "HashTable.h"
#include <string.h>

@implementation HashTable

- (int) size {
	return _size;
}

/*- (HashTable *)ctor:(int)sz {
	size = sz;
	table = (int *)malloc(sizeof(int)*size);
	
	return self;
}*/

@end
//
//  HashTableStrings.m
//  libobjcgbarm
//
//  Created by link on 25/10/12.
//  Copyright 2012 vub. All rights reserved.
//

#import "HashTableStrings.h"

@implementation HashTableStrings

- (HashTable *)ctor:(int)sz {
	_size = sz;
	_table = (int**)malloc(sizeof(NSString*)*_size);
	
	return self;
}

- (int)matchWithKey:(int)key returns:(NSString*)rString{
	if (_table > (int**)0) {
		rString = (NSString*)_table[ (sizeof(NSString*) * key) % _size ];
		return 0;
	} else {
		return -1;
	}
}

@end
//
//  HashTableTupleInts.m
//  libobjcgbarm
//
//  Created by link on 25/10/12.
//  Copyright 2012 vub. All rights reserved.
//

#import "HashTableTupleInts.h"

@implementation HashTableTupleInts

- (HashTableTupleInts *)ctor:(int)sz {
	_size = sz;
	_table = (int**)malloc(sizeof(NSString*)*_size);
	
	return self;
}

- (int)matchWithKey:(int)key returns:(NSString*)rString{
	if (_table > (int**)0) {
		rString = (NSString*)_table[ (sizeof(NSString*) * key) % _size ];
		return 0;
	} else {
		return -1;
	}
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Hex.h"

@implementation Hex 

/*
 * Table address scription
 */
- (Hex*) ctorString:(NSString*)word
{
	int i = [word length];
	//NSMutableString *s = [[NSMutableString alloc] initWithString:@""];
	if (i == 0)
		return nil;

	_hex = 0;
	while (--i >= 0) {
		char c = [word characterAtIndex: i];
		_hex |= c;//NOTE address transcription ! 
		//[s appendFormat:@"%c",c];
	}
	//memcpy(&_hex,[s UTF8String],[word length]);//NOTE little endian !

	return self;
}

- (Hex*) ctorInt:(int)h
{
	_hex = h;
	return self;
}

- (Hex*) ctor:(Hex*)h
{
	_hex = [h address];
	return self;
}

//NOTE returns NSString
- (NSString*) hexnumberstring
{
	return [NSString stringWithFormat:@"%d",_hex];
}	

- (int) number {
	return _hex;
}

- (int) getNumber {
	return _hex;
}

- (Hex*) setNumber:(int)h
{
	_hex = h;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "JavaByteCodeMachine.h"

@implementation JavaByteCodeMachine

- (JavaByteCodeMachine*)ctor
{
	_type = HAVE_MACHINE_JAVA;
	_freeaddycounter = 0;
	return self;
}

- (int)pushDefinition:(Hex*)hex with:(Hex*)hex2
{

	return 0;
}



@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "MethodNameArray.h"


@implementation MethodNameArray

- (MethodNameArray *)ctor {
	[ _methodnames ctor:256];
	return self;
}

- (int) matchMethodNameId:(int)tni {
	NSString *bogusString = nil;
	return [ _methodnames matchWithKey: tni returns:bogusString];
}

- (int) matchMethodName:(MethodName *)tn {
	NSString *bogusString = nil;
	return [ _methodnames matchWithKey: [tn type] returns:bogusString];
}

@end

/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "MethodName.h"


@implementation MethodName

- (MethodName *)ctor:(int)i withMethodName:(NSString *)n {
	[super init];
	methodid = i;
	name = n;
	return self;
}

- (NSString *)string {
	return name;
}

- (int)type {
	return methodid;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import "ObjectLocator.h"
#import "TypeName.h"

@implementation ObjectLocator

- (int) isa: (TypeName*)typename in: (GBAObject *)gbao {
		
	return [gbao isa:typename];

}
	
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Object.h"

@implementation Object

- (int) writeOn:(Disk*)disk data:(void*)data {

	if ([_typenames size] > 0) {
		//FIXME [disk write:[[_typenames objectWithIndex:0] string] data:data];
		return 0;
	} else {
		return -1;
	}
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Operator.h"

@implementation Operator

- (Operator*)defineWithName:(NSString*)name andAddress:(Hex*)address
{
	_name = name;
	_address = address;

	return self;
}

- (Hex*)address
{
	return _address;
}

- (NSString*)name
{
	return _name;
}

- (NSString*)string
{
	return _name;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "OperatorTable.h"

@implementation OperatorTable

- (OperatorTable*)ctor
{
	_array = [NSMutableArray new]; 
	return self;
}

- (Operator*) getObjectWithIndex:(int)si
{
	int i = 0;
	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if (i++ == si)
			return object;
	}

	return nil;
}

- (Operator*) getObject:(Operator*)ti
{

	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if (object == ti)
			return object;
	}

	return nil;
}

- (Operator*) getOperator:(NSString*)s
{

	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if ([[object string] compare:s] == 0)
			return object;
	}

	return nil;
}

- (int) searchForHex:(Hex*)hex
{

	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if ([[Hex new] ctor:[object string]] == hex)
			return (int)[ object type ];// | (int)[hex getNumber];FIXME
	}

	return -1;	

}

- (void) addObject:(Operator*)s
{
	[_array addObject: s];
}
/*
- (int) set:(NSString*)s1 value:(NSString*)s2
{
	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if ( s1 == [object string] ) {
			[object setValue:s2];
			return;//NOTE only set first come value (queue)
		}
	}

	return NULL;	

}
*/
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ParseString.h"


@implementation ParseString

- (ParseString*)ctor:(NSString*)s {
	[super init];
	string = s;
	
	return self;
	
}

- (bool) isSkipCharacterAtIndex:(int)index {
	if (index < [string length] && ([string characterAtIndex:index] == ' '
									||
									[string characterAtIndex:index] == '\t'
									||
									[string characterAtIndex:index] == '\n'))
		return true;
	
	else {
		return false;
	}
}

- (int) skipSkips:(int)i {
	while (i < [string length]) {
		if ([self isSkipCharacterAtIndex:i++])
			continue;
		else {
			break;
		}

	}
	return 0;
}

- (NSString*)getWordUntilCharacter:(unichar)c startingAt:(int)i {
	NSString *s;
	while (i < [string length]) 
		if ([string characterAtIndex:i] != c) {
			s += [string characterAtIndex:i];
		} else {
			return s;
		}
	return @"";
}

- (bool) eqString:(NSString*)s {
	if (s == string)
		return true;
	else {
		return false;
	}
}

- (int) isTypedWell {
	int i;
	i = [self skipSkips:i];
	
	while (++i < [string length]) {
		if ([string characterAtIndex:i] == '(')
			break;
	}
	
	i = [self skipSkips:i];
	
	
	NSString* typeword = [self getWordUntilCharacter:')' startingAt:i];//e.g void)
	NSString* typeword2 = [self getWordUntilCharacter:' ' startingAt:i];//e.g. void )
	
	//FIXME type db + object locator code
	if (typeword == @"void"
		||
		typeword == @"int"
		||
		typeword == @"NSString*") {
		return i+[typeword length];
	} else if (typeword2 == @"void"
			   ||
			   typeword2 == @"int"
			   ||
			   typeword2 == @"NSString*") {
		return i+[typeword2 length];
		
	} else {
		return -1;
	}
	
}

- (NSString*)string {
	return string;
}

- (NSString*)substringAtIndex:(int)i {
	NSString *ts = @"";
	
	int j = i;
	while (j < [string length]) {
		ts += [string characterAtIndex:j++];
	}
	
	return ts;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ParseTree.h"

@implementation ParseTree 

- (ParseTree*)ctor 
{
	_left = NULL;
	_right = NULL;
	return self;
}

- (void)setLeft:(ParseTree*)tl
{
	_left = tl;
}

- (void)setRight:(ParseTree*)tr
{
	_right = tr;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ParseTreeOpLeaf.h"

@implementation ParseTreeOpLeaf 

- (ParseTreeOpLeaf*)ctor:(NSString*)opnd
{
	_operand = opnd;
}


@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ParseTreeOp.h"

@implementation ParseTreeOp 

- (void)setOp:(char) c
{
	_op = c;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Scanner.h"


@implementation Scanner

- (int)scanFile:(FNString*)filename {
	
	[filename scan ];
	return 0;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "ScanSystem.h"


@implementation ScanSystem

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import "Stack.h"

@implementation Stack

- (void)push:(NSObject*)o {

}


@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Status.h"



@implementation Status

-(void) addStatus:(int)si {
	
	switch (si) {
		case 0:{
			break;
		}
		case NOMETHODSDECLAREDINCLASS:{
			[_statusstrs addObject: @"No methods declared in class interface."];
			break;
		}
		default:{
		}
	}
	
}

- (void) addStatusTuple:(TupleInt*)ti {
	[_statusstrs addObject:[[TupleInt new] addFirstInt:[ti first] andSecond:[ti second]]];
}

- (void) addStatus:(int)si withObject:(NSObject*)oi {
	[_statusstrs addObject:[[TupleInt new] addFirstInt:si andSecond:oi]];
}

- (Tuple*)getObject:(int)si
{
	Tuple *ti = [Tuple new];

	NSEnumerator *e = [_statusstrs objectEnumerator];
        id object;
        while (object = [e nextObject]) {
		if ([object first] == si) {
			[ti addFirstInt:e andSecond:[TupleInt new]];	
		}
        }	
	return ti; 
}

- (int)size
{
	return [_statusstrs length];
}

- (int)length
{
	return [_statusstrs length];
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import "StructureBracket.h"

@implementation StructureBracket



@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#import "Structure.h"

@implementation Structure



@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "SymbolArm.h"

@implementation SymbolArm

- (int) defineWithId:(int)typeid andName:(NSString*)name andRegisterNumber:(int) rn{

	_id = typeid;
	_name = (char *)[name UTF8String];
	_registernumber = rn;

	return 0;
	
}
- (Symbol*)ctor:(int)i withSymbolName:(NSString *)n andValue:(NSString*)val andAddress:(int)addy andRegisterNumber:(int)rn
{
	[super init];

	_id = i;
	_name = (char *)[n UTF8String];
	_address = [[Hex new]ctor:addy];
	_value = val;
	_registernumber = rn;

	//_bracedepth = bn;

	return self;
}

- (int)getRegisterNumber
{
	return _registernumber;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Symbol.h"

@implementation Symbol

- (Symbol*)ctor:(int)i withSymbolName:(Form *)n {

	[self initDocString];
	_id = i;
	_name = n;
	[self initDocString];	
	return self;
}

- (Symbol*)ctor:(int)i withSymbolName:(Form *)n andAddress:(int)addy
{
	[self initDocString];
	_id = i;
	_name = n;
	_address = [[Hex new]ctor:addy];
	return self;
}

- (Symbol*)ctor:(int)i withSymbolName:(Form *)n form:(Form*)form
{
	[self initDocString];
	_id = i;
	_name = n;
	return self;
}

- (Symbol*)ctor:(int)i withSymbolName:(Form *)n andValue:(Form*)val andAddress:(int)addy
{
	[self initDocString];
	_id = i;
	_name = n;
	_address = [[Hex new]ctorInt:addy];
	_value = val;
	return self;
}

- (Symbol*)ctorName:(NSString*)symname form:(Form*)form
{
	[self initDocString];
	_name = symname;
	_address = [[Hex alloc] ctorString:symname];
	_value = form;
	_id = formtype;
	return self;
}

- (Symbol*)ctorName:(NSString*)symname form:(Form*)form type:(TYPE)t
{
	[self initDocString];
	_name = symname;
	_address = [[Hex alloc] ctorString:symname];
	_value = form;
	_id = t;
	return self;
}

- (NSString *)string {
	return _name;
}

- (NSString *)name {
	return _name;
}

- (Form *)value {
	return _value;
}

- (int)type {
	return _id;
}

- (Hex*)address {
	return _address;
}

- (NSString*)documentation
{
	if (_documentation != nil)
		return _documentation->string;
	return nil;
}

- (void)initDocString
{
	_documentation = (struct documentation*)malloc(sizeof(struct documentation));
	_documentation->string = [[NSString alloc] initWithString:@""];
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "SymbolTableArm.h"

@implementation SymbolTableArm

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "SymbolTable.h"

@implementation SymbolTable

- (SymbolTable*)ctor
{
	_array = [NSMutableArray new]; 
	return self;
}

- (Symbol*) getObjectWithIndex:(int)si
{
	int i = 0;
	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if (i++ == si)
			return object;
	}

	return NULL;
}

- (Symbol*) getObject:(Symbol*)ti
{

	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if (object == ti)
			return object;
	}

	return NULL;
}

- (Symbol*) getString:(NSString*)s
{

	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if ([object string] == s)
			return object;
	}

	return NULL;
}

- (Symbol*) searchForHex:(Hex*)hex
{


	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		//skip null hex
		if ([[[Hex alloc] ctorString:[object name]] hexnumberstring] == nil)
			return nil;
		NSLOG3(@"%@ = %@", [[[Hex alloc] ctorString:[object name]] hexnumberstring], [hex hexnumberstring]);
		if ([[[[Hex alloc] ctorString:[object name]] hexnumberstring] compare: [hex hexnumberstring]] == 0)
			return object;/*** | (int)[hex getNumber];***///FIXME
	}

	return nil;	

}

- (void) addObject:(Symbol*)s
{
	[_array addObject: s];
}

- (int) addObjectExists:(Hex*)h form:(Form*)f type:(TYPE)t
{
	NSEnumerator *e = [_array objectEnumerator];
	id object;
	Symbol *s;
	while (object = [e nextObject]) {
		if ([[object address] number] == [h number]) {
			s = [[Symbol alloc] ctorName:[object name] form:f type:t];
			[_array removeObject:object];
			[_array addObject:s];
			return 0;
		}
	}
	return -1;
}
/*
- (int) set:(NSString*)s1 value:(NSString*)s2
{
	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if ( s1 == [object string] ) {
			[object setValue:s2];
			return;//NOTE only set first come value (queue)
		}
	}

	return NULL;	

}*/

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "TupleInt.h"

@implementation TupleInt 

-(TupleInt*)addFirst:(int)fst andSecond:(NSObject*)snd {

	first = fst;
	second = snd;

	return self;
}

-(TupleInt*)addFirstInt:(int)fst andSecond:(NSObject*)snd {

	first = fst;
	second = snd;

	return self;
}

- (int)first {
	return first;
}

- (NSObject*)second {
	return second;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "TupleIterator.h"


@implementation TupleIterator 

- (TupleIterator*)ctor:(Tuple*)t
{
	_current = t;

	return self;
}

- (Tuple*)next
{
	Tuple *t = [_current second];
	_current = t;
	return _current;
}

- (int)atEnd
{
	if (_current == NULL)
		return 1;
	else
		return 0;
} 

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#import "Tuple.h"


@implementation Tuple 

-(Tuple*)addFirst:(NSObject*)fst andSecond:(NSObject*)snd {

	first = fst;
	second = snd;

	return self;
}

- (NSObject*)first {
	return first;
}

- (NSObject*)second {
	return second;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "TypeChar.h"

@implementation TypeChar

- (TypeChar*)ctor {

	[super init];

	_id = 0x01;
	_name = (char *)@"char";
	
	return self;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "TypeInt.h"

@implementation TypeInt

- (TypeInt*)ctor {

	[super init];

	_id = 0x02;
	_name = (char *)@"char";
	
	return self;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Type.h"

@implementation Type

// bogus
- (int) defineWithId:(long int)typeid andName:(NSString*)name {

	_id = typeid;
	_name = name;
	return 0;
	
}

- (Type*)ctor:(long int)i withTypeName:(NSString *)n {
	[super init];

	_id = i;
	_name = n;
	
	return self;
}

- (NSString *)string {
	return (NSString*)_name;
}

- (int)type {
	return _id;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "TypeNameArray.h"


@implementation TypeNameArray

- (TypeNameArray *)ctor {
	[_typenames ctor:256*256];//--FIXME fixed size
	return self;
}

//seek typename's id returns 0 if found, -1 if not found, rString contains typename matched by id
- (int) matchTypeNameId:(int)tni returns:(NSString*)rString {
	[_typenames matchWithKey: tni returns:rString];
	
	if (rString > 0)
		return 0;
	else {
		memset((void *)rString, 0, sizeof(rString));
		return -1;
	}

}

//seek typename returns 0 if found -1 if not found
- (int) matchTypeName:(TypeName *)tn {
	NSString  *rString;
	[self matchTypeNameId:[tn type] returns: rString];
	
	if (rString > 0)
		return 0;
	else {
		memset((void *)rString, 0, sizeof(rString));
		return -1;
	}
}

- (int)size {
	return [_typenames size];
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "TypeName.h"

@implementation TypeName

// bogus
- (int) defineWithId:(long int)typeid andName:(NSString*)name {

	_id = typeid;
	_name = (char *)[name UTF8String];
	return 0;
	
}

- (TypeName *)ctor:(long int)i withTypeName:(NSString *)n {
	[super init];
	//////////////WRITETYPE(name);

	_id = i;
	_name = (char *)[n UTF8String];
	
	return self;
}

- (NSString *)string {
	return (NSString*)_name;
}

- (long int)type {
	return _id;
}

- (int) this:(TypeName*) tn isa:(const char *)str {
	if (!strncmp(str,[[tn string] UTF8String],strlen(str)))
		return 0;
	else
		return -1;
}

- (int) subCompileSelfOn:(Disk*)disk {


	[disk defineWith: _id and: _name toFormat:ELF];

	return 0;
}

- (int) subCompileSelfOn:(Disk*)disk withFormat:(int)fmt{
	[disk defineWith: _id and: _name toFormat:fmt];
	
	return 0;
}

- (int)writeOn:(Disk*)disk data:(Data*)data{

	//FIXME [disk write:self data:[data data]];

}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "TypeNameMem.h"
#import "string.h"

@implementation TypeNameMem

- (int) defineWithId:(int)typeid andName:(NSString*)name {
	_size = 1024;//FIXME C prog disease
	_data = calloc(_size, 1);
	 
	memmove(_data,typeid,sizeof(typeid));
	memset(_data,0,1);

	//put name in the back, reversed
	char **s;
	//ifdef ONARM char **s = &(char *)[[self reverse:name] UTF8String];
	*s = (char *)[[self reverse:name] UTF8String];
	memmove(_data+_size-sizeof(*s),*s,sizeof(*s));

	return 0;
	
}

//ctor
- (TypeNameMem *)ctor:(long int)i withTypeName:(NSString *)n {
	[super init];
	//////////////WRITETYPEMEM(name);

	[self defineWith:i andName:n];

	return self;
}

- (NSString *)string {

	char **s;
	*s = malloc(_size/2+1);
	memset(*s,0,_size/2+1);
	memcpy(*s, _data+_size/2,_size/2);	
	NSString *rs = [NSString new];
	[rs stringWithFormat:@"%@", *s];
	return [self reverse: rs];	
	
}

- (int)type {
	int **is;
	*is = malloc(_size/2+1);
	memcpy(*is,_data,_size/2);
	return *is;	
}

- (int) this:(TypeNameMem*) tn isa:(const char *)str {
	if (!strncmp(str,[[tn string] UTF8String],strlen(str)))
		return 0;
	else
		return -1;
}

- (int) subCompileSelfOn:(Disk*)disk {


	////[disk defineWith: _id and: _name toFormat:ELF];

	return 0;
}

- (int) subCompileSelfOn:(Disk*)disk withFormat:(int)fmt{
	////[disk defineWith: _id and: _name toFormat:fmt];
	
	return 0;
}

- (int)writeOn:(Disk*)disk data:(Data*)data{

	//FIXME [disk write:self data:[data data]];

}

- (NSString*)reverse:(NSString*)str {
        NSString *reversestr = @"";

        int l = [str length];
        int i = 0;
        while (i++ < l){
                reversestr += [str characterAtIndex:i];
        }

        return reversestr;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "TypeTable.h"

@implementation TypeTable

- (TypeTable*)ctor
{
	_array = [NSMutableArray new]; 
	return self;
}

- (Type*) getObjectWithIndex:(int)si
{
	int i = 0;
	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if (i++ == si)
			return object;
	}

	return NULL;
}

- (Type*) getObject:(Type*)ti
{

	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if (object == ti)
			return object;
	}

	return NULL;
}

- (int) searchForHex:(Hex*)hex
{

	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if ([object isKindOfClass:[Type class]]) {
			if ([[[[Hex alloc] ctorString:[object name]] hexnumberstring] compare: [hex hexnumberstring]] == 0)
				return (int) [object type];/*** | (int)[hex getNumber];***///FIXME
		}
	}

	return -1;	

}

- (int)hasType:(NSString*)typenamestring 
{

	NSEnumerator *e = [_array objectEnumerator];
	id object;
	while (object = [e nextObject]) {
		if ([object string] == typenamestring)
			return (int)0;
	}

	return -1;	

}

- (int)addType:(long int)typeid withName:(NSString*)name
{
	if ([self hasType:name] == 0) {//type already exists

		[_array removeObject:name];
		return 0;
	} else {

		[_array addObject:[[Type alloc] defineWithId:typeid andName:name]];
		return 0;
	}
	return -1;
}
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "TypeVoid.h"

@implementation TypeVoid

- (TypeVoid*)ctor {

	[super init];

	_id = 0x03;
	_name = (char *)@"void";
	
	return self;
}

@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
//
//  Created by link on 25/10/12.
//

#ifndef UTIL_H_
#define UTIL_H_

/*
 * This is a TypeName class as seen in libobjcgbarm
 */

#import "arm-lisp-config.h" 

void NSLOG(void*x) {
	#ifdef _DEBUG
	NSLog(x);
	#endif
};
void NSLOG2(void*x,void*y) {
	#ifdef _DEBUG
	NSLog(x,y);
	#endif
};
void NSLOG3(void*x,void*y,void*z) {
	#ifdef _DEBUG
	NSLog(x,y,z);
	#endif
};
void NSLOG4(void*x,void*y,void*z,void*xx) {
	#ifdef _DEBUG
	NSLog(x,y,z,xx);
	#endif
};
void NSLOG5(void*x,void*y,void*z,void*xx,void*yy) {
	#ifdef _DEBUG
	NSLog(x,y,z,xx,yy);
	#endif
};
void NSLOG6(void*x,void*y,void*z,void*xx,void*yy,void*zz) {
	#ifdef _DEBUG
	NSLog(x,y,z,xx,yy,zz);
	#endif
};
void NSLOG7(void*x,void*y,void*z,void*xx,void*yy,void*zz,void*xxx) {
	#ifdef _DEBUG
	NSLog(x,y,z,xx,yy,zz,xxx);
	#endif
};
#endif
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "WordBase.h"

@implementation WordBase

- (WordBase*)ctor:(NSString *)n
{
	_word = n;
	return self;
}

- (NSString*)string
{
	return _word;
}

- (int)isWord:(NSString*)w
{
	if ([_word compare: w] == 0)
		return 0;
	else
		return -1;
}
@end
/*
 Copyright (C) Johan Ceuppens 2012
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#import "Word.h"
#import "TupleInt.h"

//TODO substring
@implementation Word

- (int)isWhile
{
	return [self isWord:@"while"];	
}

- (int)isIf
{
	return [self isWord:@"if"];	
}

- (int)isParensDefun
{
	return [self isWord:@"(defun"];	
}

- (int)isParensLoop
{
	return [self isWord:@"(loop"];	
}

- (int)isParensIf
{
	return [self isWord:@"(if"];	
}

- (int)isElse
{
	return [self isWord:@"else"];	
}

- (int)isOpeningBrace
{
	return [self isWord:@"{"];	
}

- (int)isClosingBrace
{
	return [self isWord:@"}"];	
}

- (int)isElseClause
{

	TupleInt *ti = [self skipWhiteSpace:_word withIndex:0];
	int idx = [ti first];
	int idx2;
	if ([_word characterAtIndex:idx++] == '}') {

		if ([_word characterAtIndex:idx] == ' ') {
			ti = [self skipWhiteSpace:_word withIndex:idx];
		}
		if ((ti = [self subString:@"else"]) && [ti first] >= 0) {

			if (ti = [[ti second] subString:@"{"] || [ti first] >= [_word length])
				return 0;

		} 	 
	}	
	return -1;
}

- (int)isWhileClause
{

	TupleInt *ti = [self skipWhiteSpace:_word withIndex:0];
	int idx = [ti first];
	if ((ti = [_word subString:@"while"]) && [ti first] > 0) {

		if (((ti = [[ti second] subString:@"("]) || [ti first] > idx) && [ti first] < [_word length])
			return 0;

	}	
	return -1;
}

- (int)isIfClause
{

	TupleInt *ti = [self skipWhiteSpace:_word withIndex:0];
	int idx = [ti first];
	if ((ti = [self subString:@"(if"]) && [ti first] > 0)
			return 0;
	return -1;
}

- (TupleInt*)subString:(NSString*)s
{
	int idx = 0;
	for ( ; idx < [_word length] ; ) {
		int r2 = 0;
		for ( ; [_word characterAtIndex:idx] == [s characterAtIndex: r2] ; ) {
			if (r2 >= [s length]-1) {
				idx++;
				NSString *s2 = [[NSString alloc] initWithString:s];
				for ( ; idx < [_word length]; ) {//concat rest of word 
					s2 += [_word characterAtIndex:idx];
					idx++;
				}
				
				return [[TupleInt new] addFirstInt:idx andSecond:[[NSString alloc] initWithString: s2]];
			}
			r2++;
			idx++;
		}
		idx++;	
	}
	return [[TupleInt new] addFirstInt:-1 andSecond:@""];
}

- (TupleInt*)skipWhiteSpace:(NSString*)word withIndex:(int)idx
{
	NSString *s = @"";
	while (idx < [word length]) {
		char c = [word characterAtIndex:idx++];
		if (c == ' ' || c == '\t')
			;
	}

	return [[TupleInt new] addFirst:idx andSecond:@""];
}

@end
\end{verbatim}
\end{mylisting2}

\section{\large Conclusion}


\bibliographystyle{plain}
\bibliography{plasmascreen} % refs.bib

\end{document}

%%


